home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / e / amigae30a_fr.lha / AmigaE30f / E-frs.doc < prev    next >
Encoding:
Text File  |  1994-09-28  |  196.9 KB  |  5,337 lines

  1.  
  2.                 +-----------------------------------------------+
  3.                 |                                               |
  4.                 |                 Amiga E v3.0a                 |
  5.                 |           Compilateur du Langage E            |
  6.                 |          Par Wouter van Oortmerssen           |
  7.                 |                                               |
  8.                 |           Traduction : Olivier ANH            |
  9.                 |               Membre du BUGSS                 |
  10.                 |             Copyright 1994 BUGSS              |
  11.                 |                                               |
  12.                 +-----------------------------------------------+
  13.  
  14. Contenu :
  15.  
  16.          0. compilateur et introduction
  17.             A. introduction
  18.             B. la distribution
  19.             C. restrictions de la version démo et registration
  20.             D. utiliser lecompilateur
  21.             E. changement de la v2.1b à la v3.0a
  22.             F. information additionnelle
  23.  
  24.          1. format
  25.             A. tabulations, saut de ligne (lf) etc.
  26.             B. commentaires
  27.             C. identificateurs et types
  28.  
  29.          2. valeurs immédiates
  30.             A. décimales (1)
  31.             B. héxadecimales ($1)
  32.             C. binaires (%1)
  33.             D. flottants (1.0)
  34.             E. caractères ("a")
  35.             F. chaines ('bla')
  36.             G. listes ([1,2,3]) et listes typées
  37.  
  38.          3. expressions
  39.             A. format
  40.             B. priorité des opérateurs
  41.             C. types d'expressions
  42.             D. appels de fonction
  43.  
  44.          4. operateurs
  45.             A. mathématiques (+ - * /)
  46.             B. de comparaison (= <> > < >= <=)
  47.             C. logiques (AND OR)
  48.             D. unaire (SIZEOF ` ^ {} ++ -- -)
  49.             E. triple (IF THEN ELSE)
  50.             F. de structure (.)
  51.             G. de tableau ([])
  52.             H. flottants (|)
  53.             I. expressions d'assignement (:=)
  54.             J. séquence (BUT)
  55.  
  56.          5. déclaration
  57.             A. format (;)
  58.             B. labels et gotos (JUMP)
  59.             C. assignement (:=)
  60.             D. mnémoniques assembleur
  61.             E. conditionel (IF)
  62.             F. for (FOR)
  63.             G. while (WHILE)
  64.             H. repeat (REPEAT)
  65.             I. loop (LOOP)
  66.             J. select-case (SELECT)
  67.             K. incrémentation (INC/DEC)
  68.             L. expressions vides (VOID)
  69.  
  70.          6. fonction : définitions et déclarations
  71.             A. définition et arguments des procédures (PROC)
  72.             B. définitions locales et globales (DEF)
  73.             C. endproc/return
  74.             D. la fonction "main"
  75.             E. variables système prédéfinies (built-in)
  76.  
  77.          7. déclaration de constantes
  78.             A. constantes (CONST)
  79.             B. énumerations (ENUM)
  80.             C. sets (SET)
  81.             D. constantes prédéfinies (built-in)
  82.  
  83.          8. types
  84.             A. à propos du système "type"
  85.             B. letype de base (LONG/PTR)
  86.             C. le type simple (CHAR/INT/LONG)
  87.             D. le type tableau (ARRAY)
  88.             E. le type complexe (STRING/LIST)
  89.             F. le type composé (OBJECT)
  90.             G. initialisation
  91.             H. l'essentiel du système de type du E
  92.  
  93.          9. fonctions prédéfinies (built-in)
  94.             A. fonctions d'entrées-sorties (I/O)
  95.             B. chaines et fonctions de chaine
  96.             C. listes et fonctions de liste
  97.             D. fonctions de support Intuition
  98.             E. fonctions de support graphique
  99.             F. fonctions de support système
  100.             G. fonctions mathémathiques et autres fonctions
  101.             H. chaine et fonctions de lien entre listes
  102.             I. Cellule Lisp et fonctions cellulaires
  103.  
  104.         10. fonctions de bibliothèques (libraries) et modules
  105.             A. appels de bibliothèques prédéfinies (built-in)
  106.             B. interfacer le système amiga avec les modules v39
  107.             C. compiler ses propres modules
  108.             D. le module cache
  109.  
  110.         11. expressions cotées (`)
  111.             A. les cotes simple et l'analyse
  112.             B. Eval()
  113.             C. fonctions prédéfinies (built-in)
  114.  
  115.         12. support des nombres flottants
  116.             A. utilisation des flottants et fonctions d'opérateurs flottants
  117.             B. expressions flottantes et conversions
  118.  
  119.         13. gestion des exceptions
  120.             A. définition des gestionnaires d'exceptions (HANDLE/EXCEPT)
  121.             B. utilisation de la fonction Raise()
  122.             C. définition des exceptions pour les fonctions prédéfinies (RAISE/IF)
  123.             D. utilisation des identificateurs d'exception
  124.  
  125.         14. programmation orientée objet (OO)
  126.             A. Caractèristiques de l'OO en E
  127.             B. héritage des objets
  128.             C. chacher les données (EXPORT/PRIVATE/PUBLIC)
  129.             D. méthodes and méthodes virtuelles
  130.  
  131.         15. assembleur en ligne
  132.             A. les identificateurs
  133.             B. l'assembleur en ligne comparé au macro assembleur
  134.             C. comment utiliser les données binaires (INCBIN/CHAR..)
  135.             D. OPT ASM
  136.             E. assembleur en ligne et variables registres
  137.  
  138.         16. implémentations
  139.             A. le mot-clé OPT
  140.             B. le modèle small/large
  141.             C. l'organisation de la pile
  142.             D. les limites du code
  143.             E. les messages d'érreurs, d'avertissements et de non-référence
  144.             F. l'organisation des tampons du compilateur et allocation
  145.             G. allocation des registres
  146.  
  147.         17. utilitaires essentiels du E
  148.             A. ShowModule
  149.             B. ShowHunk
  150.             C. Pragma2Module / Iconvert
  151.             D. ShowCache / FlushCache
  152.             E. ecompile.rexx
  153.             F. o2m
  154.             G. E-Yacc
  155.             H. SrcGen
  156.             I. EBuild
  157.  
  158.         18. Appendices
  159.             A. la grammaire du E
  160.             B. tutorial
  161.             C. comparaison du E avec C/C++/Pascal/Ada/Lisp etc.
  162.  
  163.  
  164.  
  165. +-----------------------------------------------------------------------+
  166. |                    0. COMPILATEUR ET INTRODUCTION                     |
  167. +-----------------------------------------------------------------------+
  168.  
  169.  
  170. 0A. introduction
  171. ----------------
  172.  
  173. Le E est un langage de programmation hautement procédural, très influencé par
  174. les langages comme le C et le Modula2. C'est une langage tous azimuts, et
  175. l'implémentation sur l'Amiga est spécifiquement dirigé à la programmation
  176. d'applications systèmes.Points négatifs :
  177.  
  178. C'est ce à quoi ressemble 'Hello World' en E :
  179.  
  180. /* nominé pour l'Exemple Le Plus Ennuyant */
  181.  
  182. PROC main()
  183.   WriteF('Hello, World!\n')
  184. ENDPROC
  185.  
  186.  
  187. 0B. la distribution
  188. -------------------
  189.  
  190. La distribution inclue:
  191.  
  192. bin/            contient le compilateur EC et les utilitaires supports,
  193. modules/        Répertoire contenant tous les modules v39 ainsi des outils
  194.                 utiles à lier comme modules,
  195. docs/           documentation sur le E,
  196. src/            sources exemples en E.
  197.  
  198. Cett distribution de l'Amiga E v3.0 incluant la version de démonstration du
  199. compilateur est Freeware, et peut être librement copié. Le compilateur que
  200. certains d'entre vous aurons reçut avec cette archive, n'est cependant pas
  201. freeware, et ne doit pas être copié pour d'autres personnes sinon vous-même.
  202.  
  203. Distribuer des copies du E pour plus que le prix du disque et des frais
  204. d'envoie (en général <US$3), ou tout autre moyen de distribution avec la
  205. moindre intention de faire du profit, n'est pas autorisée.
  206.  
  207. Cette distribution doit toujours être distribuée en un seul morceau, ie dans sa
  208. forme d'archive .lha originale. Aucune addition, modifications, distribution
  209. partielle ou quoi que soit d'autre n'est permis sans ma permission.
  210.  
  211. Aucune garantie n'est donnée. Si vous utilisez le E pour noyer votre poisson
  212. rouge, ou bien le E ne vous convient pas pour commander des pizzas, c'est votre
  213. problême. Si quoi que se soit se passe, ne m'en blamez pas.
  214.  
  215. Fred Fish a un permission spéciale pour distribuer le E sur son CD-ROM.
  216.  
  217.  
  218. 0C. restrictions de la démo et enregistrement
  219. ---------------------------------------------
  220.  
  221. La distribution de l'Amiga E est Domaine Public, et contient la version de
  222. démonstration du compilateur. Les programmeurs enregistrés obtienne le
  223. compilateur entier dans une archive séparée, avec seulement "EC" dedans.
  224.  
  225. Si vous avez déja reçut un EC enregistré, vous devez le mettre dans le
  226. répertoire Bin. L'archive de distribution peut être copiée librement (voir 0B
  227. là dessus), mais faites attention de ne pas distribuer votre version
  228. enregistrée de EC, même pas à des amis. Je n'ai pas fait de série (comme des
  229. numéros d'enregistrement) pour ces copies, car j'ai confiance en mes
  230. utilisateurs enregistrés, s'il vous plait, ne la cassez pas. L'enregistrement
  231. est abordable, et la v2.1b est toujours éxistante. Il n'y a donc plus aucune
  232. excuse pour pirater le E.
  233.  
  234. Donc, qu'inclue la démo de ce compilateur ?
  235.  
  236.     Le compilateur ne vous recrachera que des éxécutables infèrieur à 12Ko,
  237.     au delà, il affichera un "workspace full" (espace de travail plein). Sinon
  238.     tout fonctionne.
  239.  
  240.     Vous avez 2 semaines pour évaluer cette démo, après celà vous décidez soit
  241.     de vous enregistrer, soit de ne plus utiliser la version démo.
  242.  
  243. Mis à jour :
  244.  
  245.     Les mises à jours pourront être trouvé dans le domaine public, et le mises
  246.     à jours pour les EC enregistrés seront distribués sous forme de patches,
  247.     aussi dans le domaine public
  248.  
  249. Commander une copie :
  250.  
  251.     Le prix de base est de $40 US.
  252.     Enlevez $5 US si vous voulez revecoir le version enregistrée de EC par
  253.     Email (uuencodé) au lieu de disquette. Celà demande une connection
  254.     _accessible_ aux Email. C'est le moyen le plus rapide de recevoir la v3.0.
  255.  
  256.     J'accepte les paiements dans d'autres monnaies, pour simplifier les choses
  257.     à certaines personnes. Pas de monnaies rare s'il vous plait.
  258.  
  259.     Exemples (US$):                         40
  260.  
  261.     Dutch Guilders (de préférence)          65
  262.     Pound Sterling anglaise                 26
  263.     DeutchMark allemand                     60
  264.     Franc français                          210
  265.     Lire italienne                          63000
  266.  
  267.     NOTE : ces prix ont été calculés au taux de change du 30 juin 1994, si
  268.     votre monnaie s'envole, à vous d'ajuster. Avoir 1$ US au dessus du prix
  269.     en Guilder n'est pas mal.
  270.  
  271. M'envoyer de l'argent :
  272.  
  273.     Ce n'est pas simple. La plupart des banques rajoutent pas mal pour faire
  274.     des tranfers d'argent. Voici quelques alternatives :
  275.  
  276.     - Envoyer de l'argent liquide (de préférence). Cela semble bizarre, mais
  277.       c'est le meilleur moyen de faire passer de l'argent. Essayez de changer
  278.       votre montant en Dutch-Guilder. Si vous n'êtes pas sûr de l'envoie, la
  279.       plupart des bureux de postes offrent un service qui vous dira que la
  280.       lettre est bien arrivée chez moi (lettre avec accusé de reception en
  281.       France).
  282.     - Transférer directement à mon compte bancaire :
  283.         427875951, ABN-AMRO bank, the netherlands (Pays Bas)
  284.       ou mon compte postal :
  285.         6030387, PostBank, the netherlands (Pays Bas)
  286.       assurez vous que vous couvrez aussi les coûts de transfer que la banque
  287.       vous chargera.
  288.     - En Europe, envoyez un EuroCheque (en Guilder). Je crois que ça ne coûte
  289.       rien, mais vérifiez toujours.
  290.     - Vous pouvez choisir d'autres méthodes, mais d'une manière générale,
  291.       réalisez que c'est à vous de vous assurer que je pourrai _facilement_
  292.       encaisser l'argent.
  293.     - N'envoyez pas de CHEQUES. Les chèques (autres que les EuroChèques)
  294.       demandent ici $15 US pour le transfer (si je peut tous les encaisser).
  295.  
  296.     Assurez vous de m'envoyer le plus d'informations possible, ie adresse
  297.     complète, adresse Email, peut-être votre configuration Amiga etc. Je ne
  298.     vais pas vous donner un stupide formulaire d'enregistrement à remplir :-)
  299.  
  300.     Mon adresse: (voir 0F)
  301.  
  302.  
  303. 0D. utiliser le compilateur
  304. ---------------------------
  305.  
  306. Pour installer l'Amiga E sur votre système, copiez simplement toute la
  307. distribution où vous le désirez sur votre système. Extendez votre chemin
  308. (path) au répertoire BIN, assignez EMODULES: au directory MODULES.
  309.  
  310. Syntaxe du compilateur (2.04+):
  311.  
  312.     SOURCE/A,REG=NUMREGALLOC/N/K,LARGE/S,SYM=SYMBOLHUNK/S,
  313.     NOWARN/S,QUIET/S,ASM/S,ERRLINE/S,ERRBYTE/S,SHOWBUF/S,
  314.     ADDBUF/N/K,IGNORECACHE/S,HOLD/S,WB/S,LINEDEBUG/S,OPTI/S:
  315.  
  316. Pour 1.2 to 2.03:
  317.  
  318.     EC [-opts] <sourcefile>
  319.  
  320. Comme exemple, on compile le programme 'HelloWorld.e'. Le compilateur va
  321. produire un éxécutable 'HelloWorld'.
  322.  
  323. 1>  ec helloworld
  324. Amiga E Compiler/Assembler/Linker v2.4f (c) 91/92/93 $#%!
  325. lexical analysing...
  326. parsing and compiling
  327. no error.
  328. 1>  helloworld
  329. Hello, World!
  330. 1>  list
  331. HelloWorld.e                  89 ----rwed Oggi      17:37:00
  332. helloworld                   656 ----rwed Oggi      17:37:00
  333. 2 files - 4 blocks used
  334.  
  335. Note : le compilateur ne peut pas être mis résident
  336.  
  337. Dernière note sur la compilation des exemples : si un programme utilise des
  338.     modules pour des définitions de bibliothèques comme :
  339.  
  340.         MODULE 'GadTools', 'Reqtools'
  341.  
  342.     le compilateur a besoin de savoir où ils se trouvent. 2 solutions sont
  343.     possibles :
  344.         1. vous faites l'assignement 'emodules:' vers le répertoire de modules
  345.            (le mieux)
  346.         2. vous spécifiez dans le code source, où chercher les modules, comme :
  347.             OPT DIR='dh0:src/e/modules'
  348.  
  349. Options du compilateur :
  350.  
  351.     Ce sont des options standards à l'AligaDos. Vous pouvez les voir à tout
  352.     moment en tapant 'EC ?'. Pour les options sous 1.2/1.3, les vieux arguments
  353.     à la UNIX sont utilisés (doivent être écrit ensemble, et précédés d'un "-":
  354.  
  355.     LARGE   -l      compile avec le GRAND (LARGE) code/donnée. Voir 16A, OPT LARGE
  356.     ASM     -a      met EC en mode assembleur. Voir 15D, OPT ASM
  357.     NOWARN  -n      supprime les avertissements. Voir 16A, OPT NOWARN
  358.     SYM     -s      ajoute un symbolhunk à l'éxécutable, en utilisation avec
  359.                     des Profilers, Debuggers, etc.
  360.     REG N   -r N    utilise N registres par PROCédure pour l'allocation
  361.                     (0 par défaut, regarder autrepart comment on l'utilise!)
  362.     QUIET   -q      si il n'y a aucune erreur ou alerte, EC n'affichera rien
  363.     WB      -w      place le wb en avant (pour les scripts)
  364.     SHOWBUF -b      montre les informations sur la memoire
  365.     ADDBUF  -mX     force EC d'allouer plus de memoire pour ses tampons (buffers).
  366.                     X compris entre 1 et 9, le nombre minimum de bloc de 100k
  367.                     à allouer. Par défaut : 1 (jamais utilisé)
  368.     ERRLINE -e      retourne le numéro de ligne où s'est produite l'erreur
  369.     ERRBYTE -E      retour l'offset de l'octet dans le fichier où s'est
  370.                     produite l'erreur
  371.     IGNORECACHE -c  n'utilise jamais le module cache
  372.     HOLD    -h      attend un <return> dans la ligne de commande avant de
  373.                     quitter EC
  374.     OPTI            autorise toutes les optimisations (actuellement égale
  375.                     REG=5)
  376.  
  377.     Exemple : ec large blabla
  378.     compile blabla.e avec le modèle large.
  379.     Note : dans la plus part des cas, vous n'aurez pas a utiliser ces options.
  380.  
  381.  
  382. 0E. Les changements de v2.1b à v3.0a
  383. ------------------------------------
  384.  
  385. Quoi de neuf dans la v3.0a:
  386. [divisé en 4 sections. Reportez vous à ce chapitre pour leur description]
  387.  
  388. 1. Les grandes nouvelles caractèristiques :
  389.  
  390. - compilation en modules [!] (voir 10C)
  391. - oo: héritage d'objets, privé/public, méthodes etc. (voir 14A)
  392. - arguments par défaut pour les PROCs (voir 6F) (et quelques builtins, aussi).
  393. - valeurs de retour multiple (voir 6G)
  394. - variables / allocation de registre (voir 16G, 15E, ...).
  395. - les réels (REALs) intégrés (voir 12)
  396. - opérateur NEW (voir 4K), et END (voir 5M) (avec une gestion super rapide de
  397.   la mémoire)
  398. - une variation syntaxique puissante de SELECT (voir 5J)
  399. - unification (voir 4L)
  400. - permet des types plus complexes dans les OBJECTs, PTR TO <type> etc.
  401.   (voir 8F) ensemble avec des réferences plus puissantes (voir 4F, x.y[a].z
  402.   etc.)
  403. - garbage collected Lisp-Cells (voir 9I)
  404. - valeurs de fonction (appel de pointeur de PROCs) (voir 6H)
  405. - module caching (voir 17D, showcache)
  406. - reconstruction d'erreur: montre exactement l'endroit de l'erreur sur la
  407.   ligne
  408. - un tas de nouvelles fonctions intégrés (voir 9A,...)
  409. - un tas de modules utiles (qui auront du poids bientôt)
  410. - des optimisations variées du compilateur qui accélère signicativement EC
  411. - plusieurs optimisations du code
  412. - système intelligent linker / module (voir 10C, entre autres)
  413. - le compilateur utilise beaucoup moins de mémoire
  414. - hunks symboliques et débbugage en ligne (voir 0D plus haut).
  415. - utilitaires variéss, tel que EE (L'éditeur E de Barry Wills),
  416.   Build (un 'make'), o2m (convertis les fichiers asm .o files en modules),
  417.   E-Yacc etc.
  418. - nouvelles docs, GRAND tutorial de Jason Hulance (plus connu sous 'Le Guide').
  419.  
  420. 2. Les caractèristiques secondaires.
  421.  
  422. - opérateur pointeur "::" (voir 4M)
  423. - EXCEPT DO: continue au handler (voir 13C)
  424. - EXIT <boolexp> dans WHILE/FOR (voir 5F)
  425. - commentaire sur une seule ligne (voir 1B)
  426. - pour quelques uns: les modules v39
  427. - les constantes caractères peuvent avoir "\n\t\e\a" "\0\\\b\q" maintenant.
  428.   (\q = ")
  429. - warning for flakey "assignments" now with linenum.
  430. - définir un PTR TO <object> avec juste des [] donne un pointeur maintenant
  431.   (par exemple x[1] = objet suivant)
  432. - un variété de petites optimisations de code
  433. - un tas de fonctions chaine/liste/entrée-sortie retourne maintenant des
  434.   valeurs de retour utiles (voir 9A,...)
  435. - la ligne de commandes de EC est du style ReadArgs() pour les utilisateurs
  436.   2.04+ (voir 0D).
  437. - meilleur fins de ligne (voir 5A)
  438. - quelques nouveaux fonctions prédéfinies (voir 9A,...)
  439.  
  440. 3. ERREURS (BUGS) / PROBLEMES FIXES.
  441.  
  442. - reconnait '.e' aussi dans la ligne de commande
  443. - plusieurs érreurs fixées (et quelques nouvelles ajoutés, tant qu'on y est)
  444. - maintenant une variable 'stdin' existe
  445. - définir un PTR TO INT avec [] donne un entier non signé au lieu d'un signé
  446.   (NOTE: ça peut changer le comportement!)
  447. - EC pouvait se planter avec des ENDIFs manquant : fixé.
  448. - CHAR s'alignait incorrectement
  449. - RAISE accepte des constantes négatives
  450. - Div() ne supportait pas les nombres négatifs
  451. - erreur asm en ligne: ADD.L ...,Ax devenait ADDX, quelques petits problêmes
  452.   bêtes
  453. - la documentation sur StringF manquait, celle de InStr() était incorrecte
  454. - SIZEOF prend les CHAR/INT/LONG aussi maintenant
  455. - WaitIMessage() fait des choses bizarres
  456. - EC ne prenait pas de très grand sources (>500k)
  457. - un WHILE ou un UNTIL avec un IF-exp comme booléen pouvait générer un code faux
  458. - [exp]:CHAR créait un code faux
  459. - quelques érreur syntaxiquepouvait être ne pas être vu
  460. - la console s'ouvrait en mode READWRITE
  461.  
  462. 4. D'autres changements que vous devez savoir
  463.  
  464. - v2.1b l'option "-s" est enlevée
  465. - 'OPT' doit être mis en premier dans le source; d'autres constructions
  466.   (comme 'CONST', 'RAISE') ont une vérifications plus stricte de leur position
  467.   dans un source
  468. - EC peut générer des erreurs internes ('internal errors') dans certains cas.
  469.   Si cela arrive, faites le moi savoir avec le source qui l'a causé
  470. - le mot-clef "IS" est équivalent à "RETURN" juste après un "PROC"
  471. - les conventions de registres de l'assembleur en ligne ont changé (voir 15B)
  472.  
  473.  
  474. Conseils aux utilisateurs de la v2.1b: comparaisons des 2 versions du fichier
  475. 'référence.doc'
  476.  
  477.  
  478. 0F. information additionnelle
  479. -----------------------------
  480.  
  481. Le compilateur Amiga E a été développé sur plus 2 ans et demi, après l'idée de
  482. l'auteur d'un bon langage de programmation, et d'un compilateur spécifique
  483. Amiga de qualité pour lui. Il a été programmé (vous l'aurez deviné) 100% en
  484. assembleur, utilisant l'assembleur AsmOne v1.02. Tous les autres programmes
  485. supports ont été écrit en E même.
  486.  
  487. Remerciements spécials pour les personnes suivantes:
  488.  
  489. Barry Wills - pour être le meilleur bétatesteur du monde
  490. Jason Hulance - pour son Guide du Débutant ('The Beginners Guide'), et comme
  491. bétatesteurss
  492. Rob Verver - pour ses commentaires/inspirations
  493. Erwin van Breemen - comme bétatesteurs
  494.  
  495. Je voudrait aussi remercier les personnes suivantes pour des raisons variées:
  496.  
  497. Raymond Hoving, Michael Zuchhi, James Cooper, Jens Gelhar, Paolo Silvera,
  498. Jeroen Vermeulen, Jan van den Baard, Joerg Wach, Norman Kraft,
  499. Urban Mueller, Charles McCreary, Olivier Anh, et plein d'autres...
  500.  
  501. Ce compilateur a été programmé avec une attention spécial sur la fiabilité
  502. et même plus sur le code généré. De plus, il a été testé et débarrassé de ses
  503. érreurs pour une longue période. Malgré tout, il n'est pas impossible qu'il
  504. contienne encore des erreurs. Si vous en trouvez, ou avez un commentaire/
  505. question, écrivez à l'adresse ci-dessous :
  506.     Je préfère _de loin_ les Emails au courrier conventionnel.
  507.  
  508. NOTE : Dû à l'immense popularité de la précédente version d'Amiga E,
  509. je recoit une quantite incroyable d'Emails auxquels je ne peux répondre.
  510. Certains d'entre eux (50%-75%) sont des questions qui ne devrait pas
  511. avoir lieu d'être si les personnes lisaient toutes les docs avec attention.
  512. Ce que je veux dire, c'est que j'aime recevoir des Emails, et répondre à
  513. des questions et aider les personnes dans leur programmation, mais consultez
  514. toutes les informations que vous avez à votre disposition comme les docs
  515. d'Amiga E ou les RKRM) pour voir si votre question est éclaircie, avant de
  516. m'envoyer un mots.
  517.  
  518.  
  519. Enregistrements (voir 0C) et donations sont les bienvenues à l'adresse:
  520.  
  521.  
  522.         Wouter van Oortmerssen ($#%!)
  523.         Levendaal 87
  524.         2311 JG  Leiden
  525.         HOLLAND
  526.  
  527. ou si vous avez un accès aux Emails:
  528.  
  529.         wouter@alf.let.uva.nl           (support programmation E)
  530.         wouter@mars.let.uva.nl          (personel)
  531.         oortmers@gene.fwi.uva.nl        (autre)
  532.  
  533.  
  534.  
  535. +---------------------------------------------------------------+
  536. |                           1. FORMAT                           |
  537. +---------------------------------------------------------------+
  538.  
  539.  
  540. 1A. tabs,lf etc.
  541. ----------------
  542.  
  543. Les sources E sont de pures fichiers ASCII, avec saut de ligne <lf> et point-
  544. virgule ";" servant de séparateurs de déclarations. Les déclarations, qui ont
  545. des arguments particuliers, séparés par une virgule ",", peuvent s'étendre
  546. sur plus d'une ligne terminée par une virgule, ignorant alors les sauts de
  547. ligne.
  548.  
  549.  
  550. 1B. commentaires
  551. ----------------
  552.  
  553. Les commentaires peuvent être placés n'importe où dans le source où
  554. normalement un espace aurait été correct. Ils commencent avec '/*' et se
  555. terminent avec '*/' et peuvent être imbriqués les uns dans les autres.
  556.  
  557.  
  558. 1C. identificateurs et types
  559. ----------------------------
  560.  
  561. Les identificateurs sont des chaines que le programmeur utilise pour
  562. caractériser certains objets, dans la plupart des cas des variables, ou même
  563. des mots-clé ou des noms de fonction prédéfinies par le compilateur. Un
  564. identificateur consiste en :
  565.  
  566.     - caractères MAJUSCULEs  et minuscules
  567.     - "0" .. "9" (sauf pour le premier character)
  568.     - "_" (le souligné)
  569.  
  570. Tous les caractères sont significatifs, mais le compilateur ne regarde que
  571. les 2 premiers pour identifier le type d'identificateur avec lequel il a
  572. affaire :
  573.  
  574. majuscule tous les deux :     - mots-clé comme IF, PROC etc.
  575.                               - constantes comme MAX_LENGTH
  576.                               - mnémoniques assembleur comme MOVE
  577. le premier en minuscule :     - identificateurs de variable/label/objet etc.
  578. premier en majuscule, second en minuscule :
  579.                               - fonctions système du E system comme WriteF()
  580.                               - appels de bibliothèque : OpenWindow()
  581.  
  582. Notez que tous les identificateurs obéissent à cette syntaxe, par exemple :
  583. WBenchToFront() devient WbenchToFront()
  584.  
  585.  
  586.  
  587. +---------------------------------------------------------------+
  588. |                      2. VALEURS IMMEDIATES                    |
  589. +---------------------------------------------------------------+
  590.  
  591. Les valeurs immédiates en E sont évaluées en 32 bits ; la seule différence
  592. parmi ces valeurs (A-G) est soit leur représentation interne, ou le fait qu'
  593. elles retournent un pointeur plutôt qu'une valeur.
  594.  
  595.  
  596. 2A. décimales (1)
  597. -----------------
  598.  
  599. Une valeur décimales est un séquence de caractères "0"..."9", avec la
  600. possibilité d'être précédé par un signe moins "-" pour les chiffres négatifs.
  601. Exemples : 1, 100 ,-12, 1024
  602.  
  603.  
  604. 2B. héxadecimales ($1)
  605. ----------------------
  606.  
  607. Une valeurs héxadécimales utilise les caractères "A"..."F" en plus, ou
  608. "a"..."f" et est précédées par un $.
  609. Exemples:
  610.     $FC, $DFF180, -$ABCD
  611.  
  612.  
  613. 2C. binaires (%1)
  614. -----------------
  615.  
  616. Les nombres binaires commencent par un "%" et n'utilise que "0" et "1" pour
  617. former une valeur.
  618. Exemples: %111, %1010100001, -%10101
  619.  
  620.  
  621. 2D. flottants (1.0)
  622. -------------------
  623.  
  624. Les flottants diffèrent des nombres décimaux de part le "." qui les séparent
  625. en deux. Une des parties peut être omise, pas les 2.
  626. Notez que le flottants ont une représentation interne de 32bits (FFP). Reportez
  627. vous au chapitre 12 pour plus d'informations.
  628. Exemples:
  629.     3.14159, .1 (=0.1), 1. (=1.0)
  630.  
  631.  
  632. 2E. caractères ("a")
  633. ---------------------
  634.  
  635. La valeur d'un caractère (encadré par des double cotes "") est leur valeurs
  636. ASCII, par ex. "A" = 65. En E, les valeurs immédiates des caractères doivent
  637. être des chaines d'au plus 4 caractères, par exemple "FORM", où le premier
  638. caractère "F" sera le poids fort (MSB) de la représentation 32 bits, et "M"
  639. le poids faible (LSB : least significant byte).
  640.  
  641.  
  642. 2F. chaines ('bla')
  643. -------------------
  644.  
  645. Les chaines sont des représentations ASCII, encadrées pour des simple cotes.
  646. La valeur de ces chaines est un pointeur sur le premier caractères.
  647. Plus spécifique : 'bla' produit un pointeur de 32 bits dans la mémoire, où
  648. on trouve les octets "b, "l", "a". TOUTES les chaines en E sont terminées
  649. par un octet zéro (0).
  650. Les chaines peuvent contenir des symboles de format introduit par "\" (anti
  651. slash), soit pour introduire des caractères dans la chaine, qui sont pour
  652. quelques raisons non affichables, soit pour formatter la chaine avec les
  653. fonctions de format telles que WriteF(), TextF() and StringF(), ou
  654. sous kick2.0, Vprintf().
  655.  
  656.     \n              saut de ligne (ascii 10)
  657.     \a ou ''        apostrophe ' (celui pour encadrer une chaine)
  658.     \e              escape (ascii 27)
  659.     \t              tabulation (ascii 9)
  660.     \\              barre oblique inverse (anti slash)
  661.     \0              octet zéro 0. D'utilisation rare, car les chaines
  662.                     finissant toutes par un zéro.
  663.     \b              retour chariot (carriage return) (ascii 13)
  664.  
  665. De plus, quand utilisé avec les fonctions de format :
  666.  
  667.     \d      affiche un nombre décimal
  668.     \h      affiche un nombre héxadecimal
  669.     \s      affiche une chaine
  670.     \c      affiche un caractère
  671.     \z      met l'octet de remplissage à '0'
  672.     \l      justifie le champ à gauche
  673.     \r      justifie le champ à droite
  674.  
  675. Les spécificateurs de champs doivent suivrent les codes \d, \h et \s :
  676.  
  677.     [x]     specifie un champ de largeur x
  678.     (x,y)   specifie le x minimum et le y maximum (chaine seulement)
  679.  
  680. Exemple: affiche un nombre héxadécimal avec 8 caractères laissant la place
  681. aux zéros :
  682.     WriteF('\z\h[8]\n',num)
  683.  
  684. Une chaine peut-être étendue sur plusieurs ligne en insérant entre eux un "+"
  685. et un saut de ligne (lf) :
  686.  
  687.     'Ceux sont 2 longues lignes ' +
  688.     'qui sont mises sur 2 lignes'
  689.  
  690.  
  691. 2G. listes ([1,2,3]) et listes typées
  692. -------------------------------------
  693.  
  694. Une liste immédiate est la partie constante du type LISTe, comme une 'chaine'
  695. est la partie constante pour une chaine ou un tableau de caractères (ARRAY OF
  696. TYPE).
  697. Exemple :
  698.  
  699.     [3,2,1,4]
  700.  
  701. est une expression qui a comme valeur un PoinTeuR sur une liste initialisée,
  702. une liste comme représentation en mémoire est compatible avec un tableau
  703. (ARRAY OF LONG), avec quelques informations en plus en offset négatif. Vous
  704. devez utiliser ces listes immédiates n'importe où, où une fonction demande un
  705. pointeur sur un tableau de valeurs 32bits, ou une liste.
  706. Exemple :
  707.  
  708.     ['chaine',1.0,2.1]
  709.     [WA_FLAGS,1,WA_IDCMP,$200,WA_WIDTH,120,WA_HEIGHT,150,TAG_DONE]
  710.  
  711. Voir la partie sur les fonctions de liste pour différencier les listes
  712. immédiates et typées, et pour des informations détailées.
  713.  
  714.  
  715.  
  716. +---------------------------------------------------------------+
  717. |                         3. EXPRESSIONS                        |
  718. +---------------------------------------------------------------+
  719.  
  720.  
  721. 3A. format
  722. ----------
  723.  
  724. Une expression est un morceau de code lié par des opérateurs, fonctions et
  725. parenthèses pour former une valeur.
  726. Il consiste dans la plupart des cas en :
  727.  
  728.     - des valeurs immédiates (chapitre 2)
  729.     - des opérateurs (chapitre 4)
  730.     - des appels de fonction (chapitre 3D)
  731.     - des parenthèses () (chapitre 3B)
  732.     - des variables ou des expressions-variables (chapitre 3C)
  733.  
  734. Exemples d'expressions :
  735.  
  736.     1
  737.     'hello'
  738.     $ABCD+(2*6)+Abs(a)
  739.     (a<1) OR (b>=100)
  740.  
  741.  
  742. 3B. priorité des opérateurs
  743. ---------------------------
  744.  
  745. Le langage E n'a pas de priorité. Cela signifie que les expressions
  746. sont évaluées de gauche vers la droite. Vous pouvez changer cette priorité
  747. en mettant entre parenthèses des (sous-)expressions :
  748.     1+2*3 /* =9 */     1+(2*3) /* =7 */       2*3+1  /* =7 */
  749.  
  750.  
  751. 3C. types d'expressions
  752. -----------------------
  753.  
  754. Il y a 3 types d'expressions qui peuvent être utilisés pour différentes
  755. applications :
  756.  
  757.     - <var>, juste une variable
  758.     - <varexp>, un variable, avec un opérateurs unaire possible
  759.       comme ++ (incrémentation) ou [] (opérateur de tableau). Pour cela,
  760.       voir les chapitre 4D et 4G. Il caractérise un expression modifiable
  761.       comme Lvaleur en C.
  762.       Notez que ces opérateurs unaires ne font pas partie des priorité.
  763.     - <exp>. Cela inclue <var> et <varexp>, et n'importe quelle autre
  764.       expression.
  765.  
  766.  
  767. 3D. appels de fonction
  768. ----------------------
  769.  
  770. Un appel de fonction est arrêt temporaire du code pour un saut vers une
  771. fonction, qui peut-être une procédure (PROC), ou juste une fonction du
  772. système. Le format d'un appel de fonction est le nom de la fonction, suivit
  773. par 2 parenthèses () encadrant de zéro à un nombre illimité d'argument,
  774. séparés par des virgules ",".
  775. Notez que les arguments de fonctions sont des expressions.
  776. Voir le chapitre 6 pour savoir comment faire sa propre fonction, et chapitre
  777. 9 et 10 pour les fonctions prédéfinis.
  778. Exemples :
  779.  
  780.     foo(1,2)
  781.     Gadget(buffer,glist,2,0,40,80+offset,100,'Cancel')
  782.     Close(handle)
  783.  
  784.  
  785.  
  786. +---------------------------------------------------------------+
  787. |                          4. OPERATEURS                        |
  788. +---------------------------------------------------------------+
  789.  
  790.  
  791. 4A. mathématiques (+ - * /)
  792. ---------------------------
  793.  
  794. Ces opérateurs combinent une expression à un autre valeur pour produire une
  795. nouvelle valeur.
  796. Exemples :
  797.  
  798.     1+2, MAX-1*5
  799.  
  800. Voir le chapitre 12 pour savoir comment utiliser les opérateurs sur les
  801. flottants.
  802. Le "-" peut être utilisé en première d'expression, avec un 0 implicite,
  803. par ex.  -a  ou -b+1  sont egaux.
  804. Notez que * et / sont par défaut des opérateurs 16 bits : Voir Mul()
  805.  
  806.  
  807. 4B. comparaison (= <> > < >= <=)
  808. --------------------------------
  809.  
  810. Idem aux opérateurs mathématiques, à la différence qu'ils renvoient soit VRAI
  811. (TRUE, valeur 32 bits = -1), ou FAUX (FALSE =0). Ils peuvent être surpassé
  812. par les flottants.
  813.  
  814.  
  815. 4C. logique (AND et OR)
  816. -----------------------
  817.  
  818. Ces opérateurs soit combinent des valeurs vraies en de nouvelles, soit
  819. réalisent des opérateurs sur des bits AND et OR.
  820. Exemples :
  821.  
  822.     (a>1) AND ((b=2) OR (c>=3))         /* logique */
  823.     a:=b AND $FF                        /* opérateur de bits */
  824.  
  825.  
  826. 4D. unaire (SIZEOF ^ {} ++ -- `)
  827. --------------------------------
  828.  
  829. - SIZEOF <objet>
  830.   retourne simplement la taille d'un objet.
  831.   Exemple: SIZEOF newscreen
  832. - {<var>}
  833.   retourne l'adresse d'une variable ou d'un label. C'est cet opérateur que
  834.   vous utiliserez pour donner une variable comme argument à une fonction par
  835.   référence, et non pas par valeur, ce qui est le défaut en E. Voir "^".
  836.   Exemple:  Val(input,{x})
  837. - ^<var>
  838.   A l'inverse de {}, il écrit ou lit des variables qui sont donnés par
  839.   référence.
  840.   Examples:      ^a:=1     b:=^a
  841.   Il est alors utilisé pour aller chercher (peek) et poser (poke) des valeurs
  842.   LONG en mémoire, si <var> est un pointeur sur cette valeur.
  843.   Exemple pour {} et ^: écrit votre fonction d'assignement :
  844.  
  845.       PROC set(var,exp)
  846.         ^var:=exp
  847.       ENDPROC
  848.  
  849.   et appelez le avec :     set({a},1)     /* egale a:=1 */
  850. - <varexp>++   et  <varexp>--
  851.   Incréménte (++) ou décrémente (--) le pointeur caractérisé par <varexp> par
  852.   par la taille des données vers lequel il pointe. Cela a pour effet que ce
  853.   pointeur pointe vers l'article (item) suivant ou précédent. Quand il est
  854.   utilisé sur des variables qui ne sont pas des pointeurs, il changera
  855.   simplement en 1. Notez que ++ prend effet _après_ le calcul de <varexp>, et
  856.   -- toujours _avant_.
  857.   Exemples :
  858.  
  859.       a++          /* retourne la valeur de a, et l'incrémente de 1 */
  860.       sp[]--       /* décrémente le pointeur sp de 4 (si il y avait un tableau),
  861.                       et lit la valeur pointée par sp */
  862. - `<exp>
  863.   On appelle un telle expression, un expression cotée, venant du LISP. <exp>
  864.   n'est pas évaluée, mais retourne l'adresse de l'expression, qui peut être
  865.   plus tard évaluéeau moment voulu. Voir le chapitre 11 pour plus
  866.   d'informations.
  867.  
  868.  
  869. 4E. triple (IF THEN ELSE)
  870. -------------------------
  871.  
  872. L'opérateur IF a presque la même fonction que la déclaration IF, seulement il
  873. choisit entre 2 expressions au lieu de 2 déclarations ou blocs de code.
  874. Il est équivalant à l'opérateur x?y:z en C.
  875.  
  876. IF <boolexp> THEN <exp1> ELSE <exp2>
  877.  
  878. retourne exp1 ou exp2, suivant l'expression booléenne boolexp. Par exemple,
  879. au lieu de :
  880.  
  881.     IF a<1 THEN b:=2 ELSE b:=3
  882.     IF x=3 THEN WriteF('x égale 3\n') ELSE WriteF('x égale autre chose\n')
  883.  
  884. écrivez:
  885.  
  886.     b:=IF a<1 THEN 2 ELSE 3
  887.     WriteF(IF x=3 THEN 'x égale 3\n' ELSE 'x égale autre chose\n')
  888.  
  889.  
  890. 4F. structures (.)
  891. -----------------
  892.  
  893. <ptr2object>.<memberofobject> forme une <varexp>
  894. Le pointeur doit être déclaré comme PTR TO <objet> ou ARRAY OF <objet>
  895. (voir le chapitre 8 pour cela), et le membre doit être un identificateur
  896. d'un objet déclaré. Notez que lire un sous objet d'un objet comme cela
  897. donne un pointeur sur cet objet.
  898. Exemple :
  899.  
  900.     cettetache.userdata:=1
  901.     rast:=monecran.rastport
  902.  
  903.  
  904. 4G. tableaux ([])
  905. -----------------
  906.  
  907. <var>[<indexexp>] (est une <varexp>)
  908. Cet opérateur lit la valeur d'un tableau sur lequel <var> pointe, et avec
  909. pour index <indexexp>. Cet index peut être simplement une expression, avec un
  910. petite limitation : il ne doit pas contenir des appels de fonction quand
  911. utilisé sur la partie gauche de l'assignement.
  912. Note 1 : "[]" est un raccourcit de "[0]"
  913. Note 2 : avec un tableau de n éléments, l'index va de 0 .. n-1
  914. Exemples:
  915.  
  916.     a[1]:=10           /* met le second élément à 10 */
  917.     x:=table[y*4+1]    /* lit le tableau */
  918.  
  919.  
  920. 4H. opérateurs flottants (|)
  921. ----------------------------
  922.  
  923. <exp>|<exp>
  924. Convertis des expressions d'entier en flottants et inversement, et surpasse
  925. les opérateurs + - * / = <> < > <= >= avec les équivalents flottants.
  926. Voir le chapitre 12 pour tout savoir sur les flottants et cet opérateur.
  927.  
  928.  
  929. 4I. expressions d'assignements (:=)
  930. -----------------------------------
  931.  
  932. Les assignements (donner une valeur a une variable) existe comme déclaration
  933. et comme expression. La seule différence est que la déclaration est de la forme
  934. <varexp>:=<exp> et l'expression <var>:=<exp>.
  935. Ce dernier a la valeur <exp> comme résultats.
  936. Notez que comme <var>:= prend une expression, vous aurez souvent besoin de
  937. parenthèses pour forcer la bonne interprétation, comme :
  938.  
  939.     IF mem:=New(100)=NIL THEN error()
  940.  
  941. est interprété comme :
  942.  
  943.     IF mem:=(New(100)=NIL) THEN error()
  944.  
  945. ce qui n'est pas ce qu'on veut : mem doit être un pointeur, pas un booléen.
  946. On doit écrire :
  947.  
  948.     IF (mem:=New(100))=NIL THEN error()
  949.  
  950.  
  951. 4J. séquence (BUT)
  952. -------------------
  953.  
  954. L'opérateur de séquence "BUT" vous permet d'écrire 2 expressions dans une
  955. construction n'en acceptnt qu'une seule. Souvent en écrivant de complexes
  956. appels de fonction, on voudrait faire une autre action 'à la volée', comme
  957. un assignement :
  958.  
  959.     <exp1> BUT <exp1>
  960.  
  961. Cela veux dire : évalue exp1, mais retourne la valeur de exp2.
  962. Exemple:
  963.  
  964.     mafonction((x:=2) BUT x*x)
  965.  
  966. assigne 2 à x, et appelle la fonction mafonction avec x*x. Les () autour
  967. de l'assignementsont nécessaire pour prévenir l'opérateur := qu'il s'agit
  968. d'une expression.
  969.  
  970.  
  971.  
  972. +---------------------------------------------------------------+
  973. |                          5. DECLARATIONS                      |
  974. +---------------------------------------------------------------+
  975.  
  976.  
  977. 5A. format (;)
  978. --------------
  979.  
  980. Comme suggéré au chapitre 1A, une déclaration est en général mise sur sa
  981. propre ligne, mais plusieurs peuvent être mise ensemble sur une seule ligne,
  982. en les séparant par un point-virgule ";", ou bien une déclaration peut être
  983. étendue sur plus d'une ligne, celles-ci finissant par une virgule.
  984. Exemples :
  985.  
  986.     a:=1; WriteF('salut!\n')
  987.     DEF a,b,c,d,             /* trop d'arguments sur la ligne */
  988.         e,f,g
  989.  
  990. Les déclarations peuvent être :
  991.     - des assignements
  992.     - des déclarations conditionelles, voir aussi les chapitres 5E-5K
  993.     - des expressions vides
  994.     - des labels
  995.     - des instructions assembleurs
  996.  
  997. La virgule est le premier caractère montrant uevous ne voulez pas terminer la
  998. déclaration avec le prochain saut de ligne (lf), mais les caractères suivants
  999. signalent la suite de la déclaration sur la ligne suivante :
  1000.  
  1001.     + - * /
  1002.     = > < <> >= <=
  1003.     AND OR BUT THEN
  1004.  
  1005.  
  1006. 5B. déclarations de labels et gotos (JUMP)
  1007. ------------------------------------------
  1008.  
  1009. Les labels sont des identificateurs globals avec un ":" à la fin :
  1010.  
  1011.     monlabel:
  1012.  
  1013. Ils peuvent être utilisés par des instructions comme JUMP, et comme référence
  1014. de données statiques. Ils peuvent être utilisés pour sortir de tous types de
  1015. boucles (cette technique n'est pas recommandée), mais pas en dehors de
  1016. procédures. Dans un programme E normal, ils sont souvent utilisés dans les
  1017. lignes assembleurs.
  1018. Les labels sont toujours très visible.
  1019.  
  1020.     JUMP <label>
  1021.  
  1022. continue l'éxécution à prtir du <label>. Vous n'êtes pas encouragé à utiliser
  1023. cette instruction, elle est là pour des situations qui devrait augmenter la
  1024. compléxité du programme si elle n'était pas là.
  1025. Exemple :
  1026.  
  1027.     IF Mouse()=1 THEN JUMP stopmaintenant
  1028.  
  1029.     /* suite du programme */
  1030.  
  1031.     stopmaintenant:
  1032.  
  1033.  
  1034. 5C. assignement (:=)
  1035. --------------------
  1036.  
  1037. Le format de base d'un assignement est :   <var> := <exp>
  1038. Exemples:
  1039.  
  1040.     a:=1
  1041.     a:=mafonction()
  1042.     a:=b*3
  1043.  
  1044.  
  1045. 5D. mnémoniques assembleurs
  1046. ---------------------------
  1047.  
  1048. En E, les lignes assembleurs font partie intégrante du langage, elles n'ont
  1049. pas besoin d'être encadré dans un blocs "ASM" spécial, comme il est usuel
  1050. dans d'autres langages, ni être assemblé par un assembleur externe pour
  1051. assembler le code. Cela veut dire qu'elles obéissent aux règles de syntaxe
  1052. du E, etc. Voir le chapitre 15 pour plus de détails.
  1053. Exemple :
  1054.  
  1055.     DEF a,b
  1056.     b:=2
  1057.     MOVEQ  #1,D0             /* quelques lignes assembleurs */
  1058.     MOVE.L D0,a              /* a:=1+b  */
  1059.     ADD.L  b,a
  1060.     WriteF('a=\d\n',a)       /* a sera égal à 3 */
  1061.  
  1062.  
  1063. 5E. déclaration conditionelle (IF)
  1064. ----------------------------------
  1065.  
  1066. IF, THEN, ELSE, ELSEIF, ENDIF
  1067.  
  1068. syntaxe:        IF <exp> THEN <déclaration> [ ELSE <instruction> ]
  1069. ou:             IF <exp>
  1070.                   <instructions>
  1071.                 [ ELSEIF <exp>           /* plusieurs elseif peuvent */
  1072.                   <instructions> ]       /* avoir lieu               */
  1073.                 [ ELSE ]
  1074.                   <instructions>
  1075.                 ENDIF
  1076.  
  1077. construit un bloc conditionnel. Notez qu'il y a 2 formes générales de cette
  1078. déclaration, en ligne unique et en ligne étendue.
  1079.  
  1080.  
  1081. 5F. instruction for (FOR)
  1082. -------------------------
  1083.  
  1084. FOR, TO, STEP, DO, ENDFOR
  1085.  
  1086. syntaxe:        FOR <var> := <exp> TO <exp> STEP <pas> DO <instruction>
  1087. ou:             FOR <var> := <exp> TO <exp> STEP <pas>
  1088.                   <instructions>
  1089.                 ENDFOR
  1090.  
  1091. construit une boucle FOR. Notez les 2 formes générales. <pas> est une
  1092. constante positive ou négative, à l'exclusion de 0.
  1093. Exemple :
  1094.  
  1095.     FOR a:=1 TO 10 DO WriteF('\d\n',a)
  1096.  
  1097.  
  1098. 5G. intruction while (WHILE)
  1099. ----------------------------
  1100.  
  1101. WHILE, DO, ENDWHILE
  1102.  
  1103. syntaxe:        WHILE <exp> DO <instruction>
  1104. ou:             WHILE <exp>
  1105.                   <instructions>
  1106.                 ENDWHILE
  1107.  
  1108. construit une boucle while, qui est répétée tant que <exp> est vraie (TRUE).
  1109. Notez les 2 formes générales.
  1110.  
  1111.  
  1112. 5H. instruction repeat (REPEAT)
  1113. -------------------------------
  1114.  
  1115. REPEAT, UNTIL
  1116.  
  1117. syntaxe:        REPEAT
  1118.                 UNTIL <exp>
  1119.  
  1120. contruit un block en boucle repeat-until : la boucle sera répétée jusqu'à ce
  1121. que <exp> soit vraie (TRUE) .
  1122. Exemple :
  1123.  
  1124.     REPEAT
  1125.       WriteF('Vous voulez vraiment sortir du programme ?\n')
  1126.       ReadStr(stdout,s)
  1127.     UNTIL StrCmp(s,'oui !')
  1128.  
  1129.  
  1130. 5I. instruction loop (LOOP)
  1131. ---------------------------
  1132.  
  1133. LOOP, ENDLOOP
  1134.  
  1135. syntaxe:        LOOP
  1136.                   <instructions>
  1137.                 ENDLOOP
  1138.  
  1139. construit une boucle infinie.
  1140.  
  1141.  
  1142. 5J. instruction select-case (SELECT)
  1143. ------------------------------------
  1144.  
  1145. SELECT, CASE, DEFAULT, ENDSELECT
  1146.  
  1147. syntax:e        SELECT <var>
  1148.                 [ CASE <exp>
  1149.                   <intructions> ]
  1150.                 [ CASE <exp>
  1151.                   <instructions> ]   /* autant de bloc de ce type */
  1152.                 [ DEFAULT
  1153.                   <instructions> ]
  1154.                 ENDSELECT
  1155.  
  1156. construit un bloc select-case. De nombreuses expressions vont être comparées
  1157. à la variable, et seulement le premier bon bloc sera éxécuté. Si rien n'est
  1158. trouvé, le bloc par défaut est éxécuté.
  1159.  
  1160.     SELECT caractère
  1161.       CASE 10
  1162.         WriteF('He, j'ai trouvé un saut de ligne\n')
  1163.       CASE 9
  1164.         WriteF('Ouah, ca doit être une tabulation!\n')
  1165.       DEFAULT
  1166.         WriteF('Vous connaissez celui là : \c ?\n',caractère)
  1167.     ENDSELECT
  1168.  
  1169.  
  1170. 5K. instruction d'incrémentation (INC/DEC)
  1171. ------------------------------------------
  1172.  
  1173. INC, DEC
  1174.  
  1175. syntaxe:        INC <var>
  1176.                 DEC <var>
  1177.  
  1178. raccourcit de <var>:=<var>+1 et <var>:=<var>-1. La seule différence avec
  1179. <var>++ et <var>-- est que INC et DEC sont des instructions, et ne retourne
  1180. aucune valeur, et sont plus efficient.
  1181.  
  1182.  
  1183. 5L. expressions vide (VOID)
  1184. ---------------------------
  1185.  
  1186. VOID
  1187.  
  1188. syntaxe:         VOID <exp>
  1189.  
  1190. calcule l'expression sans que le résultat n'aille quelque part. Utile
  1191. seulement pour une syntaxe claire, comme les expressions peuvent être
  1192. utilisées comme intruction sans VOID en E ! Cela peut provoquer une subtile
  1193. érreur : alors que "a:=1" assigne à a la valeur 1, "a=1" est une instruction
  1194. qui ne fait rien. E vous le signalera si cela arrive.
  1195.  
  1196.  
  1197.  
  1198. +---------------------------------------------------------------+
  1199. |            6. DEFINITIONS DE FONCTIONS ET DECLARATIONS        |
  1200. +---------------------------------------------------------------+
  1201.  
  1202.  
  1203. 6A. définition et arguments des procédures (PROC)
  1204. -------------------------------------------------
  1205.  
  1206. Vous devez utiliser PROC et ENDPROC pour définir les instructions dans vos
  1207. propres fonction. Ces fonctions peuvent avoir plusieurs arguments, mais
  1208. retourne une seule valeur.
  1209.  
  1210. syntaxe:        PROC <label> ( <args> , ... )
  1211.                 ENDPROC <valeur_retournée>
  1212.  
  1213. définie une procédure avec un nombre d'arguments. Les arguments sont de type
  1214. LONG ou de type PTR TO <type> (voir chapitre 8) et n'ont pas besoin d'autre
  1215. déclaration.
  1216. La fin de la procédure est désigné par ENDPROC. Si aucune valeur n'est donnée,
  1217. 0 est retournée.
  1218. Exemple : écrire une fonction qui retourne la somme de 2 arguments :
  1219.  
  1220.  
  1221.     PROC add(x,y)         /* x et y sont des variables locales */
  1222.     ENDPROC x+y           /* retourne le résultat */
  1223.  
  1224.  
  1225. 6B. définitions locales and globales (DEF)
  1226. ------------------------------------------
  1227.  
  1228. Vous devez définir des variables locales en plus de celles qui sont définies
  1229. avec DEF. Le plus simple est :
  1230.  
  1231.     DEF a,b,c
  1232.  
  1233. déclare les identificateurs a, b et c de votre fonction.
  1234. Notez que ces déclarations doivent être au début de votre fonction.
  1235.  
  1236. syntaxe:        DEF <déclarations>,...
  1237. description:    déclare les variables. Une déclaration est une de ces formes:
  1238.                 <var>
  1239.                 <var>:<type>              where <type>=LONG,<objet>
  1240.                 <var>[<taille>]:<type>    where <type>=ARRAY,STRING,LIST
  1241.  
  1242. Voir le chapitre 8 pour plus d'exemples, c'est là que les types sont introduit.
  1243. A partir de maintenant, on utilisera l'écriture <var>.
  1244. Les arguments de fonctions sont réduits aux types simples : voir chapitre 8B.
  1245. Une déclaration de type simple peut avoir une initiaisation. Dans cette
  1246. version elle doit être faite par un entier (pas d'expression) :
  1247.  
  1248.     DEF a=1,b=2
  1249.  
  1250. Un programme consiste en une suite de fonctions, appellé procédures, PROC.
  1251. Chacune d'elles puevent avoir des variables locales, et le programme en son
  1252. entier, peut avoir des variables globales. Enfin, une procédure doit être
  1253. un PROC main(), car c'est cette procédure qui est éxécutée en premier. Un
  1254. programme simple peut ressembler à ça :
  1255.  
  1256.     DEF a, b                /* définition des variables globales */
  1257.  
  1258.     PROC main()             /* l'ordre des fonctions peut être */
  1259.       bla(1)                /* mis au hasard                   */
  1260.     ENDPROC
  1261.  
  1262.     PROC bla(x)
  1263.       DEF y,z               /* possibilité de variables locales */
  1264.     ENDPROC
  1265.  
  1266. Pour résumer, les définitions locales sont celles que vous faites au début
  1267. des procédures, et qui ne sont visible qu'à l'intérieure de celles-ci.
  1268. Les définitions globales sont faites avant le premier PROC, au début de votre
  1269. source, et ils sont visibles dans toutes les procédures.
  1270. Les variables globales et locales (et bien sûr les variables locales de 2
  1271. différentes fonctions) peuvent avoir le même nom ; les variables locales ont
  1272. toujours la priorité sout les variables globales.
  1273.  
  1274.  
  1275. 6C. endproc/return
  1276. ------------------
  1277.  
  1278. Comme décrit plus haut, ENDPROC marque la fin d'une définition de fonction, et
  1279. peuvent retourner une valeur. De plus RETURN peux être utilisé n'importe où
  1280. dans la fonction pour en sortir. Si il est utilisé dans la procédure main(),
  1281. on sortira du programme. Voir aussi CleanUp() au chapitre 9F.
  1282.  
  1283.     RETURN [<valeur_retournée>]          /* optionel */
  1284.  
  1285. Exemple:
  1286.  
  1287.     PROC getresources()
  1288.       /* ... */
  1289.       IF error THEN RETURN FALSE  /* quelque s'est mal passé, on sort */
  1290.       /* ... */
  1291.     ENDPROC TRUE   /* on est allé aussi loin, on retourne TRUE */
  1292.  
  1293. Une version très raccourcit d'un définition de fonction peu-être :
  1294.  
  1295.     PROC <label> ( <arg> , ... ) RETURN <exp>
  1296.  
  1297. Ce sont des définitions de fonctions qui ont besoin de peu de calcul, comme
  1298. les fonctions de puissances et associé : (en une ligne :-)
  1299.  
  1300.     PROC fac(n) RETURN IF n=1 THEN 1 ELSE fac(n-1)*n
  1301.  
  1302.  
  1303. 6D. la fonction "main"
  1304. ----------------------
  1305.  
  1306. La procédure appelée main a son importance, car elle est appelé en première ;
  1307. elle fonctionne de la même minère que les autres fontions, et peut donc avoir
  1308. des variables locales. Main n'a pas d'arguments : les arguments de la ligne
  1309. de commande (du shell) sont fournis par la variable système "arg", ou peuvent
  1310. être collectée avec ReadArgs().
  1311.  
  1312.  
  1313. 6E. variables système prédéfinies (built-in)
  1314. --------------------------------------------
  1315.  
  1316. Les variables globales suivantes sont toujours accessible au sein du programme.
  1317. Ils sont appellés variables système :
  1318.  
  1319. arg             Vu plus haut, arg contient un pointeur sur une chaine terminée
  1320.                 par un zéro. arg contient les arguments de la ligne de
  1321.                 commande. Ne l'utilisez pas si vous voulez utiliser ReadArgs().
  1322. stdout          Contient le gestionnaire de fichier de la sortie et de
  1323.                 l'entrée standard. Si votre programme est lancé du workbench,
  1324.                 aucune sortie shell n'est possible. WriteF() ouvrira une
  1325.                 fenêtre CON: pour vous, et mettra son gestionnaire là.
  1326. conout          Ces de là que le gestionnaire de fichier est pris et la
  1327.                 fenêtre console sera automatiquement fermée à la fin de votre
  1328.                 programme. Voir WriteF() dans le chapitre 9A pour savoir
  1329.                 comment utiliser proprement les variables.
  1330. execbase,       Ces 5 variables sont toujours définies avec leur valeur
  1331. dosbase,        correcte.
  1332. gfxbase,
  1333. intuitionbase,
  1334. mathbase
  1335. stdrast         Pointeur sur le rastport standard utilisé dans votre
  1336.                 programme, ou bien NIL. Les fonctions graphique prédéfinies
  1337.                 comme Line() utilisent cette variable.
  1338. wbmessage       Contient un pointeur sur un message reçu si le programme est
  1339.                 lancé du workbench, sinon NIL. Il peut être utilisé comme
  1340.                 variable booléenne pour détecter si vous vous êtes partis du
  1341.                 workbench, ou pour pour collecter les arguments d'éventuelles
  1342.                 icones cliquées. Voir le programme WbArgs.e dans le
  1343.                 répertoire sources/exemples, pour savoir comment bien
  1344.                 l'utiliser.
  1345.  
  1346.  
  1347.  
  1348. +---------------------------------------------------------------+
  1349. |                  7. DECLARATION DE CONSTANTES                 |
  1350. +---------------------------------------------------------------+
  1351.  
  1352.  
  1353. 7A. constantes (CONST)
  1354. ----------------------
  1355.  
  1356. syntaxe:         CONST <déclarations>,...
  1357.  
  1358. Vous permet de déclarer une constante. Une déclaration ressemble à :
  1359.     <ident>=<valeur>
  1360.  
  1361. Les constantes doivent être en majuscule, et seront traité dans le reste du
  1362. programme comme <valeur>.
  1363. Exemple :
  1364.  
  1365.     CONST MAX_LINES=100, ER_NOMEM=1, ER_NOFILE=2
  1366.  
  1367. Vous ne pouvez pas déclarer des constantes dans les mêmes termes qu'une autres
  1368. dans la même instruction CONST. Mettez le dans une autre.
  1369.  
  1370.  
  1371. 7B. énumerations (ENUM)
  1372. -----------------------
  1373.  
  1374. Les énumérations sont un type de constante particulier, qui n'ont pas besoin
  1375. de valeur, car ils sont définis de 0 à n ; le premier étant égal à zéro. A
  1376. n'importe quel moment de l'énumération, vous pouvez utiliser la notation
  1377. '=<valeur>' pour fixer ou remettre à zéro le compteur.
  1378. Exemple :
  1379.  
  1380.     ENUM ZERO, ONE, TWO, THREE, MONDAY=1, TUESDAY, WEDNESDAY
  1381.  
  1382.     ENUM ER_NOFILE=100, ER_NOMEM, ER_NOWINDOW
  1383.  
  1384.  
  1385. 7C. sets (SET)
  1386. --------------
  1387.  
  1388. Les sets sont du même type que les énumérations, à la différence qu'au lieu
  1389. d'augmenter leur valeur (0,1,2,...), on augmenter leur nombre de bit
  1390. (0,1,2,...) et donc leur valeur deviennent (1,2,4,8,...). Cela a pour avantage
  1391. qu'ils peuvent être utilisés comme des drapeaux (flags).
  1392. Supposez un set comme celui--ci pour décrire les propriété d'un fenétre :
  1393.  
  1394.     SET SIZEGAD,CLOSEGAD,SCROLLBAR,DEPTH
  1395.  
  1396. pour initialiser une variable au pripriété DEPTH et SIZEGAD :
  1397.  
  1398.     winflags:=DEPTH OR SIZEGAD
  1399.  
  1400. pour ajouter un SCROLLBAR :
  1401.  
  1402.     winflags:=winflags OR SCROLLBAR
  1403.  
  1404. et pour tester si 2 propriétés sont pris en compte :
  1405.  
  1406.     IF winflags AND (SCROLLBAR OR DEPTH) THEN /* ... */
  1407.  
  1408.  
  1409. 7D. constantes prédéfinies (built-in)
  1410. -------------------------------------
  1411.  
  1412. Les constantes suivantes sont prédéfinies et peuvent être utilisées :
  1413.  
  1414. TRUE,FALSE      Représente les valeurs booléennes (-1,0)
  1415. NIL             (=0), le poineur non initialisé
  1416. ALL             Utilisé avec les fonctions de chaine comme StrCopy() pour
  1417.                 copier tous les caractères
  1418. GADGETSIZE      taille minimum en octets nécessaire pour définir un gadget ;
  1419.                 voir Gadget() au chapitre 9D
  1420. OLDFILE,NEWFILE Paramètres de mode à utiliser avec Open()
  1421. STRLEN          A toujours la longueur de la dernière chaine utilisée.
  1422.                 Exemple :
  1423.  
  1424.                 Write(handle,'Salut tous le monde!',STRLEN)      /* =20 */
  1425.  
  1426.  
  1427.  
  1428. +---------------------------------------------------------------+
  1429. |                           8. TYPES                            |
  1430. +---------------------------------------------------------------+
  1431.  
  1432.  
  1433. 8A. à propos du système "type"
  1434. ------------------------------
  1435.  
  1436. Le E n'a pas une système de type rigid comme le Pascal ou le Modula2, il est
  1437. même plus flexible que clui du C : on doit plutôt l'appeler un système de type
  1438. de donnée (datatype system). Il en résulte qu'en E tous les types de données
  1439. sont égaux : toutes les valeurs simples comme les carctères, entiers, etc.
  1440. Ils ont tous la même taille de 32 bits, et les autres types comme les tableaux,
  1441. les chaines sont représentées par des pointeurs de 32 bits pointant sur eux.
  1442. Ainsi, le compilateur E peut générer un code de façon très polymorphe.
  1443. Les (dés)avantages sont nombreux :
  1444.  
  1445.     désavantages :
  1446.  
  1447.     - peu de vérification sur des érreurs que vous faites.
  1448.  
  1449.     avantages :
  1450.  
  1451.     - polymorphisme de bas niveau,
  1452.     - programmation très flexible : aucune crainte de voir certaines valeurs
  1453.       retournées, ne correspondant pas à la variable cible, etc.,
  1454.     - facilité de retrouver des érreurs lors de mélange de données
  1455.       d'expressions de taille différentes,
  1456.     - bénéficie de types 'auto-documentés', si vous voulez comme ça :
  1457.  
  1458.           PTR to newscreen
  1459.  
  1460.  
  1461. 8B. le type simple (LONG/PTR)
  1462. -----------------------------
  1463.  
  1464. Il n'y a qu'un seul simple et non-complexe type en E, qui est le type
  1465. LONG de 32 bits. Comme c'est le type par défaut, il peut être déclaré comme :
  1466.  
  1467.     DEF a:LONG             ou juste:            DEF a
  1468.  
  1469. Ce type de variable a les mêmes caractèristiques que les types
  1470. CHAR/INT/OTR/LONG d'autres langages. Un variation de LONG est le type pointeur
  1471. PTR. Ce type est compatible avec le LONG, à la différence qu'il est spécifié
  1472. en tant que pointeur. Par défaut, le type LONG est spécifié comme PTR TO CHAR.
  1473.  
  1474. Syntaxe:    DEF <var>:PTR TO <type>
  1475.  
  1476. où le <type> est de type simple ou composé.
  1477. Exemple :
  1478.  
  1479.     DEF x:PTR TO INT, mon_écran:PTR TO screen
  1480.  
  1481. Notez que 'screen' est le nom d'un objet défini par le module
  1482. 'intuition/screens.m'. Par exemple, si vous ouvrez votre propre écran avec :
  1483.  
  1484.     mon_écran:=OpenS(...   etc.
  1485.  
  1486. vous devez utiliser le pointeur mon_écran tout comme 'mon_écran.rastport'.
  1487. Si vous ne voulez pas utiliser cette variable jusqu'à la fermeture de l'écran
  1488. par CloseS(mon_écran), vous pouvez simplement le déclarer comme :
  1489.  
  1490.     DEF mon_écran
  1491.  
  1492.  
  1493. 8C. le type simple (CHAR/INT/LONG)
  1494. ----------------------------------
  1495.  
  1496. Les types simples CHAR (8 bits) et INT (16 bits) ne doivent pas être utilisés
  1497. pour des variables de base. La raison de cela doit être clair maintenant.
  1498. Malgré tout, ils peuvent être utilisés comme type de données pour construire
  1499. des tableaux, ou poser des pointeurs, ou être utilisé dans des objets, etc.
  1500.  
  1501.  
  1502. 8D. le type tableau (ARRAY)
  1503. ---------------------------
  1504.  
  1505. Les tableaux sont déclarés en spécifiant leur longueur en octets :
  1506.  
  1507.     DEF b[100]:ARRAY
  1508.  
  1509. définie un tableaux de 100 octets. De façon interne, b est une variable de type
  1510. LONG et un pointeur sur cet espace mémoire.
  1511. Le type par défaut d'un élément du tableau est CHAR, mais peut être autre
  1512. chose en le spécifiant :
  1513.  
  1514.     DEF x[100]:ARRAY OF LONG
  1515.     DEF mes_menus[10]:ARRAY OF newmenu
  1516.  
  1517. où 'newmenu' est une exemple de structure (appelé OBJEcT en E).
  1518. L'accès au tableau est très simple :
  1519.     <var>[<exp>]
  1520. Exemples :
  1521.  
  1522.     b[1]:="a"
  1523.     z:=mes_menus[a+1].mutualexclude
  1524.  
  1525. Notez que l'index d'un tableau de taille n, est définis de 0 à n-1,
  1526. et pas de 1 à n.
  1527. Notez que les tableaux de type x (ARRAY OF <type>) est compatible avec les
  1528. pointeurs sur un type x (PTR TO <type>, à la différence que la variable
  1529. tableau est déja initialisée.
  1530.  
  1531.  
  1532. 8E. le type complexe (STRING/LIST)
  1533. ----------------------------------
  1534.  
  1535. - STRING (chaine). Similaire aux tableaux, mais différent dans le sens
  1536.   qu'elles ne peuvent être modifiées que par les fonctions de chaines du E,
  1537.   et qu'ils contiennent les informations de longueurs (length et maxlength).
  1538.   Ainsi les fonctions de chaines peuvent les modifier sans crainte : la
  1539.   chaine ne peut pas être plus grande que l'espace mémoire où elle est.
  1540.  
  1541.   Syntaxe :     DEF s[80]:STRING
  1542.  
  1543.   Le type de données STRING est rétroactivement compatible avec PTR TO CHAR
  1544.   et bien sûr ARRAY TO CHAR, et c'est tout.
  1545.   Voir la chapitre sur les fonctions de chaines pour plus de détails.
  1546.  
  1547. - LIST (liste). C'est un type de donnée que l'on ne retrouve que dans
  1548.   d'autres langages comme le Prolog ou le Lisp. La version E peut être
  1549.   interprétée comme un mélange de chaine et de tableaux de LONG :
  1550.   cette structure de données est une liste de variables LONG qui peuvent
  1551.   être étendu ou résumé à des chaines.
  1552.  
  1553.   Syntaxe :     DEF x[100]:LIST
  1554.  
  1555.   Un plus puissant à ce type de données est qu'il a un équivalent 'constant'
  1556.   [], comme les chaines ont ''. Les listes sont rétroactivement compatible
  1557.   avec PTR TO lONG et bien sûr ARRAY OF LONG, et c'est tout.
  1558.   Voir les chapitres 2G et 9C pour plus d'informations.
  1559.  
  1560.  
  1561. 8F. le type composé (OBJECT)
  1562. ----------------------------
  1563.  
  1564.   Les objets sont l'équivalent des structures en C ou RECORD en Pascal.
  1565.   Exemple :
  1566.  
  1567.       OBJECT myobj
  1568.         a:LONG
  1569.         b:CHAR
  1570.         c:INT
  1571.       ENDOBJECT
  1572.  
  1573.   définie une structure de données de 3 éléments.
  1574.  
  1575.   Syntaxe:      OBJECT <nom_objet>
  1576.                   <nom_membre> [ : <type> ]      /* autant que vous voulez */
  1577.                 ENDOBJECT
  1578.  
  1579.   où le type est un type simple ou composé, ou un tableau simple :
  1580.   [<nb_éléments>]:ARRAY avec par défaut, la taille CHAR pour un élément.
  1581.   Notez que <nom_membre> peut ne pas être seul, et peut se trouver dans
  1582.   d'autres objets. Il y a beaucoup de manière d'utiliser les objets :
  1583.  
  1584.       DEF x:mon_objet                  /* x est une structure */
  1585.       DEF y:PTR TO mon_objet           /* y est juste un pointer dessus */
  1586.       DEF z[10]:ARRAY OF mon_objet
  1587.  
  1588.       y:=[-1,"a",100]:myobj            /* listes typées */
  1589.  
  1590.       IF y.b="a" THEN /* ... */
  1591.  
  1592.       z[4].c:=z[d+1].b++
  1593.  
  1594.   Les tableaux dans les objets sont toujours arrondis à la taille paire,
  1595.   et mis sur des offsets pairs :
  1596.  
  1597.       OBJECT machaine
  1598.         longueur:CHAR,
  1599.         donnée[9]:ARRAY
  1600.       ENDOBJECT
  1601.  
  1602.   La taille (SIZEOF) de 'machaine' est de 12, et 'donnée' commence à
  1603.   l'offset 2.
  1604.  
  1605.   NOTE : les objet du E ne sont pas ce que vous imaginez dans d'autres
  1606.   langages. Par exemple, pas seulement les types peuvent former un membre
  1607.   d'un objet, et grace à ça, des accès récursif aux objets comme x.y.z
  1608.   non aucun sens (pour le moment).
  1609.  
  1610.  
  1611. 8G. initialisation
  1612. ------------------
  1613.  
  1614. 1. Sont toujours initialisées à NIL (or autres, si explicitement décrit)
  1615.     - les variables globales,
  1616.       NOTE : pour une bonne documentation, il est conseillé d'écrire
  1617.       xxx =NIL dans la définition de variables qui vous voulez l'avoir nulle
  1618. 2. Sont initialisées à '' et respectivement []
  1619.     - les chaines globales et locales
  1620.     - les listes globales et locales
  1621. 3. Ne sont pas initialisés
  1622.     - les variables locales (tant qu'elle ne sont pas définies explicitement)
  1623.     - les tableaux globals et locaux
  1624.     - les objets globals et locaux
  1625.  
  1626.  
  1627. 8H. l'essentiel du système de type du E
  1628. ---------------------------------------
  1629.  
  1630. Cette section essaie d'expliquer comment le système de type du E d'un point
  1631. de vue différent.
  1632.  
  1633. La plupart des problêmes que les gens ont en programmant en E provient de
  1634. leur mauvaise connaissance sur le fonctionnement du système de type E. De même,
  1635. beaucoup d'entre-eux ont une idée sur le fonctionnement provenant d'un autre
  1636. langage, et essaye de l'appliqué en E, ce qui est souvent fatal, car le E est
  1637. tout différent quant on en vient aux types.
  1638.  
  1639. Le système de type:
  1640.     le E est par essense un langage SANS type. En fait des variables peuvent
  1641.     avoir un type, mais il est alors uniquement utilisé comme spécifications
  1642.     sur la définition d'une variable lorsqu'il est utilisé comme pointeur. Dans
  1643.     quasiment TOUS les autres contructions des langages, les variables sont
  1644.     traités comme étant du même type, code sur une valeur sans type de 32 bits.
  1645.  
  1646.     En pratique cela signifie que par exemple dans des expressions avec des
  1647.     exceptions des opérateurs ".", "[]" et "++" etc., tous les opérateurs et
  1648.     fonctions travaillent sur des valeurs sur 32 bits, sans regarder si c'est
  1649.     un  booléens, entiers, réels, pointeurs sur quelquechose.
  1650.  
  1651. Les types de pointeur:
  1652.     Dans le système de type, seulement 4 types existent, PTR TO CHAR,
  1653.     PTR TO INT, PTR TO LONG et PTR TO <objet>, où <objet> est le nom d'un
  1654.     OBJECT défini précédemment. Quand une variable (où un membre d'un object,
  1655.     comme on le verra plus tard) est déclarée comme étant de ce type. Ca
  1656.     signifie que si la variable contient une valeur qui est un pointeur legal,
  1657.     c'est comment il doit être définit.
  1658.  
  1659. LONG, ARRAY etc.
  1660.     Tous les autres types qu'on peut voir dans les déclarations DEF ne sont
  1661.     pas réellement des types, car c'est une autre façon d'écrire un des 4
  1662.     types. Comme exemple, AEEAY OF <type> est juste une autre façon d'écrire
  1663.     PTR TO <type>, avec la seule différence que le premier est automatiquement
  1664.     assigné à une adresse d'un espace de pile suffisamment grand pour prendre
  1665.     les données du nombre d'éléments spécifiés entre crochets.
  1666.  
  1667. Ci-dessous se trouve une table qui montre tous les 'types' E en termes des 4
  1668. de bases:
  1669.  
  1670. ARRAY OF CHAR, ARRAY, STRING, LONG   (sont égals à)   PTR TO CHAR
  1671. ARRAY OF INT                         (est égale to)   PTR TO INT
  1672. ARRAY OF LONG, LIST                  (sont égale à)   PTR TO LONG
  1673. ARRAY OF <objet>, <objet>            (sont égale à)   PTR TO <objet>
  1674.  
  1675. - LONG est pour les variables qui ne sont pas utilisé comme pointeur,
  1676.   i.e entiers. Son équivalence avec PTR TO CHAR est logique, car sur le
  1677.   plan du concept, tous 2 parlent de choses mesuré en unité 1.
  1678.   (par exemple, "++" a le même effet sur les 2)
  1679. - LIST et STRING sont les mêmes que leurs équivalents tableaux ('ARRAY'),
  1680.   à part le fait qu'ils sont initialisés dans un morceau de la pile, mais
  1681.   leur représentation dans la pile est un petit peu plus complexe pour
  1682.   faciliter la vérification pendant le runtime ('runtime bounds-checking')
  1683.   (quand utilisé avec les bonnes fonctions).
  1684. - un <objet> est équivalent à [1]:ARRAY OF <objet>. Tous 2 représentent un
  1685.   PTR TO <objet> initialisés.
  1686.  
  1687. Dans un OBJECT, on peut avoir les mêmes déclarations, avec l'ajout de CHAR
  1688. et INT 'similaire à LONG), et l'ommission de LIST et STRING, comme ils sont
  1689. des objets complexes de leur plein droit, et ne peuvent être partis d'un objet.
  1690.  
  1691. Définition:
  1692. Ayant un pointeur p d'un type donné,
  1693.  
  1694. "[]" peut indéxer d'autres éléments qui sont séquentiellement ordonnés après
  1695.      l'élément qui est actuellement pointé. Notez qu'il permet des indices
  1696.      positifs et négatifs, et aussi aucune supposition n'est faites sur où et
  1697.      combien d'éléments sont actuellement alloués.
  1698.  
  1699. "++" mets le pointeur sur l'élément suivant en mémoire, "--" sur l'élément
  1700.      précédent. Notez que ces opérateurs opèrent toujours sur des pointeurs
  1701.      et jamais sur l'élément sur lequel pointeur pointe.
  1702.  
  1703. "."  est similaire à "[]", seulement indexe le pointeur par le nom, ie le
  1704.      pointeur doit être un PTR TO <objet>.
  1705.  
  1706. "[]" et "." peuvent être concatené à un pointeur p dans n'importe quelle
  1707.      séquence, sachant que la valeur précédente retournée doit être du type
  1708.      "PTR TO".
  1709.  
  1710. On n'a pas besoin d'écrire une définition en entier, comme dans d'autres
  1711. langages, eg si p est un ARRAY OF <objet>, au lieu d'avoir à écrire
  1712. p[index].membre vous pouvez juste écrire p[index], qui donne logiquement
  1713. l'adresse de cet objet. Ca explique alors pourquoi p[].membre est équivalent à
  1714. p.membre, tant que p[] est le même p lorsqu'il pointe sur un objet.
  1715.  
  1716. Sémantique par Référence (Reference Semantics):
  1717.     Un autre type qui fait du E un peu différent des autres langages et donc
  1718.     difficle à comprendre est son penchant pour les sémantiques par références,
  1719.     plutôt que des sémantiques par valeur. J'essaye d'argumenter pourquoi c'est
  1720.     bien.
  1721.  
  1722.     Informellement, les sémantiques par référence signifient que les objets
  1723.     dans un langage (autre que le type simple comme LONG) sont représentés par
  1724.     des pointeurs, alors que les sémantiques par valeur traitent ces objets
  1725.     comme valeurs propres. Un exemple de langage qui n'a que des sémantiques
  1726.     par valeurs est le BASIC, des exemples de langages qui ont les 2 sont les
  1727.     langages de type C/C++ et le Pascal, et des exemples de référence seul
  1728.     sont les nouveaux langages Orientés Objets, langages fontionnels comme le
  1729.     LISP et bien sûr le E.
  1730.  
  1731. Utiliser les sémantiques par référence ne signifie pas occuper des
  1732. pointeurs tout le temps. Vous avez besoin de moins vous en préoccuper dans
  1733. les cas mixtes ou les cas valeurs-uniquement. Particulièrement dans des
  1734. programmes réels, les structures de données sont allouées dynamiquement
  1735. ce qui implique des pointeurs. Le meilleur exemple de cela est le LISP,
  1736. où on programme avec des pointeurs sans s'en apercevoir. En E, on peut
  1737. facilement oublier que STRING est un pointeur, connaissant la facilité
  1738. de copie vers d'autres fonctions ; en C souvent un tas de "&" est nécessaire
  1739. alors qu'en cas équivalent E, aucun ne l'est, et l'équivalent Oberon de
  1740. bla('hallo') ressemble à bla(sys.ADR('hallo')) parce que la chaine ne
  1741. représente pas un pointeur, mais une valeur à part entière...
  1742.  
  1743.  
  1744.  
  1745. +---------------------------------------------------------------+
  1746. |                     9. FONCTIONS PREDEFINIES                  |
  1747. +---------------------------------------------------------------+
  1748.  
  1749.  
  1750. 9A. fonctions d'entrée - sortie (I/O)
  1751. -------------------------------------
  1752.  
  1753.  
  1754. WriteF(formatstring,args,...)
  1755.  
  1756.     affiche une chaine (qui peut contenir des codes de format) vers stdout. De
  1757.     zéro à un nombre illimité d'arguments peut être ajoutés. Notez qu'une
  1758.     chaine formattée peut être crée dynamiquement, aucune vérification sur le
  1759.     nombre d'arguments est (peut être) fait.
  1760.     Exemple :
  1761.  
  1762.         WriteF('salut à tous!\n')       /* juste écrit un saut de ligne à */
  1763.                                         /* la fin de la chaine */
  1764.  
  1765.         WriteF('a = \d \n',a)           /* écrit : "a = 123", si a est 123 */
  1766.  
  1767.     Voir le morceau concernant les chaines, quelque part par ici.
  1768.     NOTE : si stdout=NIL, par exemple si votre programme a été lancé du
  1769.     Workbench, WriteF() ouvrira une fenêtre de sortie (uniquement sous 2.0),
  1770.     et mettra le gestionnaire dans conout et stdout. Cette fenêtre sera
  1771.     automatiquement refermée à la sortie du programme, après que l'utilisateur
  1772.     aie frappé <return>.
  1773.     WriteF() est la seule fonction qui ouvre une fenêtre, donc si vous voulez
  1774.     faire des entrées/sorties sur stdout, et pour être sûr que stdout<>NIL,
  1775.     faites un WriteF('') comme première instruction de votre programme par
  1776.     sécurité.
  1777.     Si vous voulez ouvrir une fenêtre console vous même, vous devez faire de
  1778.     la sorte de placer le résultat du gestionnaire de fichier (file handle)
  1779.     dans les variables stdout et conout, comme ça votre fenêtre sera fermé
  1780.     automatiquement à la fin du programme.
  1781.     Si vous voulez fermer vous même votre fenêtre, assurez vous de remettre
  1782.     conout à NIL, pour signaler au E qu'il n'y a aucune fenêtre console à
  1783.     fermer.
  1784.  
  1785.  
  1786. Out(gestionnaire,car)
  1787. char:=Inp(gestionnaire)
  1788.  
  1789.     D'une part écrit, d'autre part lit un octet vers un fichier ou sur stdout.
  1790.     Si car=-1 alors un EOF est atteint, ou une érreur s'est passée.
  1791.  
  1792.  
  1793. longueur:=FileLength(nom_chaine)
  1794.  
  1795.     vous donne la longueur d'un fichier que vous voulez charger, et donc si
  1796.     il éxiste ; ou retourne -1 pour une érreur ou si il n'est pas trouvé.
  1797.  
  1798.  
  1799. ok:=ReadStr(filehandle,estring)
  1800.  
  1801.     Voir les fonctions de chaines
  1802.  
  1803.  
  1804. oldout:=SetStdOut(newstdout)
  1805.  
  1806.     Fixe la variable de sortie standard stdout. C'est l'équivalent de :
  1807.  
  1808.         oldout:=stdout ; stdout:=newstdout
  1809.  
  1810.  
  1811. 9B. chaines et fonctions de chaine
  1812. ----------------------------------
  1813.  
  1814. Le E possède le type de données STRING. C'est une chaine, appelée à partir de
  1815. maintenant chaine E ('Estring'), qui peut être modifiée et changée en taille,
  1816. à opposer à la chaine normale ('string'), qui sera utilisé pour n'importe
  1817. quelle séquence terminée par un zéro.
  1818. Les chaines E sont rétroactivement compatible avec les chaines, et rien
  1819. d'autres. Alors si un argument demande une chaine normale, on y mettre
  1820. indifféremment l'une des 2 chaines. Si parcontre une chaine E est demandée,
  1821. n'utilisez pas une chaine normale.
  1822. Exemple :
  1823.  
  1824.     DEF s[80]:STRING, n            /* s est une chaine E avec une  */
  1825.                                    /* longueur maximum de 80       */
  1826.     ReadStr(stdout,s)              /* lit un entrée sur la console */
  1827.     n:=Val(s,NIL)                  /* et en sort une valeur        */
  1828.         ... etc.
  1829.  
  1830. Notez que toutes les fonctions de chaine sont gérer de façon à tendre vers
  1831. leur longueur maximum correctement
  1832.  
  1833.     DEF s[5]:STRING
  1834.     StrAdd(s,'ceci est une chaine de 5 caractères',ALL)
  1835.  
  1836. s va contenir 'ceci '.
  1837.  
  1838.  
  1839. s:=String(maxlen)
  1840.  
  1841.     Une chaine peut donc allouer dynamiquement en mémoire système avec la
  1842.     fonction String(), (note: le pointeur retourné par cette fonction doit
  1843.     toujours être vérifiée.
  1844.  
  1845.         DEF s[80]:STRING
  1846.  
  1847.     est équivalent à :
  1848.  
  1849.         DEF s
  1850.         s:=String(10)
  1851.  
  1852.  
  1853. bool:=StrCmp(chaine1,chaine2,long)
  1854.  
  1855.     compare 2 chaines.
  1856.  
  1857.     long        est le nombre d'octet à comparer, ou ALL pour comparer
  1858.                 toute la longueur.
  1859.     Retourne :  TRUE ou FALSE
  1860.  
  1861.  
  1862. StrCopy(chaineE,chaine,long)
  1863.  
  1864.     copie le chaine vers la chaine E
  1865.  
  1866.     long : nombre d'octet à copier ou ALL
  1867.  
  1868.  
  1869. StrAdd(chaineE,chaine,len)
  1870.  
  1871.     fait comme StrCopy(), à la différence que la chaine est mis à la fin
  1872.     de la chaine E (concaténation)
  1873.  
  1874.  
  1875. long:=StrLen(chaine)
  1876.  
  1877.     calcule la longueur d'une chaine terminée par un zéro.
  1878.  
  1879.  
  1880. long:=EstrLen(chaineE)
  1881.  
  1882.     retourne la longueur d'un chaine E.
  1883.  
  1884.  
  1885. max:=StrMax(chaineE)
  1886.  
  1887.     retourne la longueur maximale d'un chaine E
  1888.  
  1889.  
  1890. RightStr(chaineE1,chainE2,n)
  1891.  
  1892.     copie les n derniers caractères de la chaine 1 dans la chaine 2
  1893.  
  1894.  
  1895. MidStr(chaineE1,chaine2,pos,long)
  1896.  
  1897.     copie un nombre de caractère (long) (tous si long=ALL) à partir de la
  1898.     position pos de la chaine 2 sur la chaine 1.
  1899.     NOTEZ : dans toutes les fonctions de chaines, le premier caractères à la
  1900.     position 0 et non pas 1, comme c'est le cas dans des langages comme le
  1901.     BASIC.
  1902.  
  1903.  
  1904. valeur:=Val(chaine,lecture)
  1905.  
  1906.     trouve un entier dans une chaine ASCII. Les espaces/tabulations/etc...
  1907.     sont sauté, et ainsi les nombres héxadécimaux (123456789abcdef) et
  1908.     binaire (01) peuvent être lu de cette manière si ils sont précédés par
  1909.     un '$' ou un '%' respectivement. Un '-' signifie un entier négatif.
  1910.     Val() retourne le nombre de caractères lu, dans 'lecture', qui doit être
  1911.     donné par référence (<-!!!). Si 'lecture' retourne 0 (et la valeur sera
  1912.     aussi 0), alors la chaine ne contient pas d'entier, ou la valeur et trop
  1913.     grande pour entré dans 32 bits. 'lecture' peut être NIL.
  1914.  
  1915.     Exemples de chaines qui seront correctement analysées :
  1916.         '-12345', '%10101010', '   -$ABcd12'
  1917.  
  1918.     Ces chaines seront retournés en tant que 'valeur' et dans une variable
  1919.     {lu} un zéro :
  1920.         '', 'hello!'
  1921.  
  1922.  
  1923. quelle_pos:=InStr(chaine1,chaine2,pos_départ)
  1924.  
  1925.     cherche dans la chaine 1, la chaine 2, a partir du caractère pos_départ.
  1926.     L'*adresse* a laquelle la chaine 2 a été retrouvé, est retournée, sinon -1.
  1927.  
  1928.  
  1929. nouv_adr_chaine:=TrimStr(chaine)
  1930.  
  1931.     retourne l'*adresse* du premier caractère, après avoir enlevé les espaces,
  1932.     tabulations, etc...
  1933.  
  1934.  
  1935. UpperStr(chaineE)
  1936. LowerStr(chaineE)
  1937.  
  1938.     Transforme les minuscule en masjuscule (respectivement masjuscule en
  1939.     minuscule)
  1940.     NOTE : ces fonctions modifient le contenu de 'chaine'. On ne peut donc
  1941.     utiliser que des chaines E. Cela suppose que vous obteniez l'adresse d'une
  1942.     chaine grace à une fonctions de l'Amiga. Vous devez alors faire une copie
  1943.     (par StrCopy()) de cette chaine dans une chaine E, puis utiliser ces
  1944.     fonctions.
  1945.  
  1946.  
  1947. ok:=ReadStr(gest_fichier,chaineE)
  1948.  
  1949.     lit une chaine (se terminant par le code ASCII 10) de n'importe quel
  1950.     fichier ou de stdout.
  1951.     ok contient -1 si il y a erreur, ou une fin de fichier (EOF) si on est
  1952.     à la fin.
  1953.     NOTE : le contenu de la chaine lue est toujours valide.
  1954.  
  1955.  
  1956. SetStr(chainE,nouv_long)
  1957.  
  1958.     modifie manuellement la longueur d'une chaine E. C'est pratique lorsque
  1959.     qu'une fonction autre que les fonctions E, lit une chaine E, et vous
  1960.     voulez continuer à utiliser cette variable.
  1961.     Par exemple, après avoir utilisé une fonction qui ajoute un zero à la fin
  1962.     d'un chaine E, prenez SetStr(ma_chaine,StrLen(ma_chaine)) pour manipuler
  1963.     ma_chaine à nouveau.
  1964.  
  1965. Pour les fonctions liant les chaines, voir la chapitre 9H
  1966.  
  1967.  
  1968. 9C. listes et fonctions de liste
  1969. --------------------------------
  1970.  
  1971. Les listes sont comme les chaines, à la différence qu'elles consistent en
  1972. LONG, et pas en CHAR.
  1973. Elles peuvent être declarées en globale, locale ou dynamiquement :
  1974.  
  1975.     DEF maliste[100]:LIST        /* local ou global */
  1976.     DEF a
  1977.     a:=List(10)                  /* dynamique */
  1978.  
  1979. Note que dans le dernier cas, le pointeur 'a' contient NIL
  1980. Tout comme les chaines sont représentées comme constantes dans les
  1981. expressions, les listes ont aussi cette possibilité :
  1982.  
  1983.     [1,2,3,4]
  1984.  
  1985. La valeur d'une telle expression est un pointeur sur une liste initialisée.
  1986. Il en résulte que vous pouvez alors avoir une déclaration dynamique, qui sera
  1987. remplit au moment même de la déclaration :
  1988.  
  1989.     a:=3
  1990.     [1,2,a,4]
  1991.  
  1992. De plus, les listes peuvent avoir d'autres types que LONG par défaut :
  1993.  
  1994.     [1,2,3]:INT
  1995.     [65,66,67,0]:CHAR                    /* équivalent à 'ABC' */
  1996.     ['topaz.font',8,0,0]:textattr
  1997.     OpenScreenTagList(NIL,[SA_TITLE,'Mon Ecran',TAG_DONE])
  1998.  
  1999. Comme le dernier exemple le montre, les listes sont très utiles dans les
  2000. fonctions système : elles sont rétroactivement compatible avec les tableaux
  2001. (ARRAY OF LONG). Les objects peuvent être utilisé n'importe où une fonction
  2002. à besoin d'un pointeur sur une structure, ou un tableau.
  2003. Les fonctions de listes de tags (taglist) et les arguments (vararg) peuvent
  2004. être utilisé de cette façon.
  2005. NOTE : toutes les fonctions de listes travaillent avec des listes de LONG.
  2006. Les listes typées ne sont pratiques que pour construire des structures et des
  2007. expressions.
  2008.  
  2009. Comme pour les chaines, une certaine hiérarchie est de rigueur :
  2010. variables de liste -> listes de constantes -> tableau de LONG/pointeur sur LONG
  2011. Quand une fonction a besoin d'un tableau de LONG, vous n'avez qu'à donner une
  2012. liste comme argument, mais quand une fonction demande une variable de liste
  2013. (listvar) ou une liste de constante, alors un tableau de LONG ne marchera pas.
  2014.  
  2015. Il est important que vous compreniez la puissance des listes et en particulier
  2016. les listes typées : elles peuvent vous éviter beaucoup soucis lors du codage
  2017. d'une structure de données. Essayez d'utiliser ces listes dans vos propres
  2018. programmes, et regardez en les fonctions dans les programmes exemples. Une fois
  2019. que vous aurez pris le coup, vous ne pourrez vous en passer !
  2020.  
  2021. Résumé :
  2022.  
  2023.     [<élément>,<élément>,... ]          liste immédiate (de LONGs, à utiliser
  2024.                                         avec les fonctions de liste)
  2025.     [<élément>,<élément>,... ]:<type>   listes typées (pour construire des
  2026.                                         structures)
  2027.  
  2028. Si <type> est un type simple comme INT ou CHAR, vous n'avez que l'équivalent
  2029. initialisé d'un tableau de <type>.
  2030. Si <type> est le nom d'un objet, vous devez construire cet objet, ou un
  2031. tableau d'<objet>, suivant la longueur de la liste.
  2032. Exemple :
  2033.  
  2034.     [1,2,3]:INT
  2035.  
  2036. vous créez une structure de 6 octets, de 3 fois 16 bits pour être précis. La
  2037. valeur de cette expression est un pointeur sur cette espace mémoire. Il en va
  2038. de même si vous avez un objet :
  2039.  
  2040.     OBJECT mon_object
  2041.       a:LONG, b:CHAR, c:INT
  2042.     ENDOBJECT
  2043.  
  2044. écrire
  2045.  
  2046.     [1,2,3]:mon_object
  2047.  
  2048. signifiera la création d'un structure en mémoire de 8 octets, avec les 4
  2049. premiers octets étant un LONG de valeur 1. L'octet suivant et un CHAR de
  2050. valeur 2, et les 2 derniers octets un INT (2 octets) de valeur 3. Vous pouvez
  2051. aussi écrire :
  2052.  
  2053.     [1,2,3,4,5,6,7,8,9]:mon_object
  2054.  
  2055. vous créez un tableau de <mon_objet> de taille 3. Notez que de telles listes
  2056. n'ont pas besoin d'être complêtes (3,6,9... éléments), vous pouvez créer
  2057. partiellement des objets avec des listes de n'importe quelle taille.
  2058.  
  2059. Une dernière note sur la taille des données :
  2060. Sur l'Amiga, vous remarquerez qu'une structure comme 'mon_objet' a une taille
  2061. de 8, et rempli à 16 pour avoir un mot. Il est certainement peu probable
  2062. qu'un compilateur E pour une architecture 80x86 n'utilisera pas ce
  2063. remplissage et en fera une structure de 7 octets, et qu'un compilateur pour
  2064. une architecture sun-sparc (si je ne me trompe pas) essayera de remplire à 32
  2065. bits, qui fera une structure de 10 ou 12 octets. Certains microprocesseurs
  2066. (rares, pas existants) utilise même les nombres de bits 38:18:9 pour leur type
  2067. LONG:INT:CHAR, au lieu de 32:16:8, comme on le fait. Alors, ne concluez pas
  2068. trop vite en ce qui concerne les objets et les listes, si vous voulez que
  2069. votre code soit portable au maximum, ou n'aie d'effets secondaires.
  2070.  
  2071.  
  2072. ListCopy(listevar,liste,n)
  2073.  
  2074.     copie n éléments de la <liste> sur la <listevar>.
  2075.     Exemple :
  2076.         DEF maliste[10]:LIST
  2077.         ListCopy(maliste,[1,2,3,4,5],ALL)
  2078.  
  2079.  
  2080. ListAdd(listvar,liste,n)
  2081.  
  2082.     copie n éléments de la <liste> à la fin de <listevar>.
  2083.  
  2084.  
  2085. ListCmp(list1,list2,n)
  2086.  
  2087.     compare les 2 listes, ou n éléments d'elles.
  2088.  
  2089.  
  2090. long:=ListLen(liste)
  2091.  
  2092.     retourne la longueur de la <liste>.
  2093.     Exemple :
  2094.         ListLen([a,b,c])    retourne 3
  2095.  
  2096.  
  2097. max:=ListMax(listevar)
  2098.  
  2099.     retourne la longueur maximale possible de <listevar>
  2100.  
  2101.  
  2102. valeur:=ListItem(liste,index)
  2103.  
  2104.     est l'équivalent de : valeur:=liste[index]
  2105.     à la différence que <liste> doit être une constante au lieu d'être un
  2106.     pointeur. C'est treès utile dans des cas où vous voulez directement
  2107.     utiliser une liste de valeurs :
  2108.  
  2109.         WriteF(ListItem(['ok!','pas de mem!','pas de fichier!'],erreur))
  2110.  
  2111.     Cet exemple écrit un message d'erreur en fonction d'<erreur>.
  2112.     C'est l'équivalent de :
  2113.  
  2114.     DEF dummy:PTR TO LONG
  2115.     dummy:=['ok!','pas de mem!','pas de fichier!']
  2116.     WriteF(dummy[error])
  2117.  
  2118.  
  2119. SetList(listevar,nouv_long)
  2120.  
  2121.     fixe manuellement la longueur d'une liste. C'est seulement utile lorsque
  2122.     vous lisez utiliser des listes par des fonctions autres que les fonctions
  2123.     spécifiques aux listes, et aue vous voulez continuer à l'utiliser comme
  2124.     vraie liste.
  2125.  
  2126.  
  2127. Pour les fonstion de liste qui utilise des expressions cotées '', voir le
  2128. chapitre 11C.
  2129. Pour les fonctions liant les listes, voir le chapitre 9h.
  2130.  
  2131.  
  2132. 9D. fonctions de support Intuition
  2133. ----------------------------------
  2134.  
  2135. wptr:=OpenW(x,y,largeur,hauteur,IDCMP,wdrapeaux,titre,écran,sdrapeaux,gadlist)
  2136.  
  2137.     crée une fenêtre où :
  2138.     - wdrapeaux (wflags) sont des drapeaux pour la mise en forme de la fenêtre
  2139.       comme BACKDROP, SIMPLEREFRESH... en général $f
  2140.     - sdrapeaux (sflags) est le type d'écran où doit s'ouvrir la fenêtre
  2141.       1 = workbench, 15 = particulier (custom)
  2142.     - screen est un pointeur sur l'écran qui doit être valide si sdrapeux = 15
  2143.       sinon screen=NIL (0)
  2144.     - gadlist pointe sur une structure de liste de gadgets, que vous pouvez
  2145.       facilement créer avec la fonction Gadget(), sinon NIL.
  2146.  
  2147.  
  2148. CloseW(wptr)
  2149.  
  2150.     ferme la fenêtre de nouveau. La seule différence avec CloseWindow()
  2151.     (fonction système) est qu'elle accepte le pointeur null (NIL) et remet
  2152.     stdrast à zéro (NIL).
  2153.     - wptr est le pointeur donné par OpenW() ou OpenWindow() pour cette
  2154.       fenêtre.
  2155.  
  2156.  
  2157. sptr:=OpenS(largeur,hauteur,profondeur,sdrapeaux,titre)
  2158.  
  2159.     ouvre un écran pour vous.
  2160.     - profondeur est le nombre de plan de bit (bitplanes) (1 à 6, 1 à 8 pour
  2161.       les machines AGA),
  2162.     - sdrapeaux est le type de résolutions, 0 pour basse résolution, $8000
  2163.       pour haute résolution, ajoutez 4 pour l'entrelacement
  2164.  
  2165.  
  2166. CloseS(sptr)
  2167.  
  2168.     ferme l'écran. Fonctionne de même facon que CloseW().
  2169.     - wptr est le pointeur donné par OpenS() ou OpenScreen() pour cet écran.
  2170.  
  2171.  
  2172. tampon_suivant:=Gadget(tampon,gadlist,id,drapeaux,x,y,largeur,chaine)
  2173.  
  2174.     Cette fonction crée une liste de gadgets, qui peuvent être mis dans votre
  2175.     fenêtre en les donnant comme argument à OpenW(), ou après l'ouverture
  2176.     avec une fonctions Intiotin comme AddGlist().
  2177.     - tampon (buffer) est souvent un tableaux de taille GADGETSIZE octets
  2178.       pour sauver toutes les structures associées à un gadget,
  2179.     - id est le n'importe quelle nombre vous permettent de vous rappeler de
  2180.       quel gadget il s'agit lorsqu'il est pressé,
  2181.     - drapeaux : 0 = gadget normal
  2182.                  1 = gadget booléen (interrupteur)
  2183.                  3 = gadget booléen pressé
  2184.     - largeur est la largeur en pixel. Il doit être suffisament grand pour
  2185.       contenir la chaine qui est auto-centrée,
  2186.     - gadlist doit être NIL pour le premier gadget, puis glistvar pour le
  2187.       tampon suivant, comme ça le E poura faire le lien entre les gadgets.
  2188.     La fonction retourne un pointeur sur le tampon suivant
  2189.     (=tampon+GADGETSIZE).
  2190.     Exemple pour 3 gadgets :
  2191.  
  2192.         CONST MAXGADGETS=GADGETSIZE*3
  2193.  
  2194.         DEF tampon[MAXGADGETS]:ARRAY, suivant, wptr
  2195.  
  2196.         suivant:=Gadget(tampon,NIL,1,0,10,20,80,'bla')  /* le premier gadget */
  2197.         suivant:=Gadget(suivant,tampon,... )
  2198.         suivant:=Gadget(suivant,tampon,... )          /* n'importe lequel  */
  2199.                                                       /* lie les 2 premiers */
  2200.  
  2201.         wptr:=OpenW( ...,buf)
  2202.  
  2203.     Regardez les exemples comme SuperVisor.e pour une exemple parlant.
  2204.  
  2205.  
  2206. code:=Mouse()
  2207.  
  2208.     donne l'état actuel des 2 ou 3 boutons de la souris ;
  2209.     1 = gauche, 2 = droit, 4 = centre
  2210.     Si par exemple code=3 alors les boutons gauches est droit sont pressés.
  2211.     NOTE : ce n'est pas une réelle fonction Intuition. Si vous voulez connaitre
  2212.     les évènements de la souris de manière propre, regardez dans la structure
  2213.     intuimessage que votre fenêtre recoit.
  2214.     C'est la seule fonction du E qui contrôle le hardware, et n'est utile aue
  2215.     dans des programmes de style démos.
  2216.  
  2217.  
  2218. x:=MouseX(fenêtre)
  2219. y:=MouseY(fenêtre)
  2220.  
  2221.     vous permet de lire les coordonnées de la souris.
  2222.     - fenêtre est le pointeur sur la fenêtre par rapport à laquelle les
  2223.     coordonnées seront relatives
  2224.  
  2225.  
  2226. classe:=WaitIMessage(fenêtre)
  2227.  
  2228.     Cette fonction rend plus facile l'attente d'un évènement dans une fenêtre.
  2229.     Elle attend simplement qu'un message intuition arrive, et retourne la
  2230.     classe de cet évènement. Elle mets les autres variables comme le code
  2231.     comme variables globales privées, afin d'y accéder grace aux fonctions
  2232.     ci-dessous.
  2233.     WaitImessages est l'équivalent du code suivant :
  2234.  
  2235.         PROC waitimessage(win:PTR TO window)
  2236.           DEF port,mes:PTR TO intuimessage,class,code,qual,iaddr
  2237.           port:=win.userport
  2238.           IF (mes:=GetMsg(port))=NIL
  2239.             REPEAT
  2240.               WaitPort(port)
  2241.             UNTIL (mes:=GetMsg(port))<>NIL
  2242.           ENDIF
  2243.           class:=mes.class
  2244.           code:=mes.code             /* sauvé en interne */
  2245.           qual:=mes.qualifier
  2246.           iaddr:=mes.iaddress
  2247.           ReplyMsg(mes)
  2248.         ENDPROC class
  2249.  
  2250.     comme vous le voyez, la fonction prend exactement un message, et n'oubliez
  2251.     pas qu'il peut arriver plusieurs messages dans un évènement, si appelé
  2252.     plus d'une fois.
  2253.     Par exemple, ovus ouvrez une fenêtre qui affiche quelque chose et attend
  2254.     que l'on presse sur le gqdget de fermeture de l'écran (vous avez spécifiez
  2255.     IDCMP_CLOSEWINDOW) à l'ouverture de la fenêtre) :
  2256.  
  2257.         WaitIMessage(ma_fenêtre)
  2258.  
  2259.     ou vous avez un programme qui attend plusieurs types d'évènement, les gére
  2260.     dans une boucle, et sort avec le gadget de fermeture :
  2261.  
  2262.         WHILE (class:=WaitIMessage(win))<>IDCMP_CLOSEWINDOW
  2263.           /* gestion de classes */
  2264.         ENDWHILE
  2265.  
  2266.  
  2267. code:=MsgCode()
  2268. qual:=MsgQualifier()
  2269. iaddr:=MsgIaddr()
  2270.  
  2271.     Ces fonctions vous donneront les variables globales privées mentionnées
  2272.     plus haut. Les valeurs retournnées sont définies d'après l'appel le plus
  2273.     récent de WaitIntuiMessage().
  2274.     Exemple :
  2275.  
  2276.     IF class:=IDCMP_GADGETUP
  2277.       mon_gadget:=MsgIaddr()
  2278.       IF mon_gadget.userdata=1 THEN  /* ... on a pressé le gadget #1 */
  2279.     ENDIF
  2280.  
  2281.  
  2282. 9E. fonctions de support graphique
  2283. ----------------------------------
  2284.  
  2285. Toutes les fonctions de support graphique qui n'implique pas directement
  2286. un rastport, utilise la variable système 'stdrast'. Elle est automatiquement
  2287. définie par le dernier appel de OpenW ou OpenS(), et remis à NIL avec CloseW()
  2288. et CloseS.
  2289. Appeler ces fonctions avec stdrast égal à NIL est légal. stdrast peut être
  2290. manuellement modifié par SetStdRast() ou stdrast:=mon_rastport.
  2291.  
  2292.  
  2293. Plot(x,y,couleur)
  2294.  
  2295.     dessine un point sur l'écran/fenêtre dans la couleur voulue.
  2296.     - couleur = 0 à 31, 0 à 255 pour les machines AGA.
  2297.  
  2298.  
  2299. Line(x1,y1,x2,y2,colour)
  2300.  
  2301.     trace une ligne
  2302.  
  2303.  
  2304. Box(x1,y1,x2,y2,colour)
  2305.  
  2306.     trace une boite
  2307.  
  2308.  
  2309. Colour(avant,fond)
  2310.  
  2311.     fixe les couleurs des fonctions graphiques qui ne prennent pas de couleur
  2312.     comme argument. C'est le *registre* de couleur qui est demandé, pas la
  2313.     *valeur*.
  2314.     NOTE : les fonctions qui ont un argument de 'couleur', modifie le Apen du
  2315.     stdrast.
  2316.  
  2317.  
  2318. TextF(x,y,chaine_formattée,args,...)
  2319.  
  2320.     tout comme la fonction WriteF(), mais uniquement à (x,y) sur votre
  2321.     stdrast, au lieu de stdout.
  2322.     Voir WriteF() et les chaines
  2323.  
  2324.  
  2325. anc_rast:=SetStdRast(nouv_rast)
  2326.  
  2327.     change le rastport de sortie des fonctions graphiques du E
  2328.  
  2329.  
  2330. SetTopaz(taille)
  2331.  
  2332.     fixe la police de caractères (font) du rastport 'stdrast'. Assurez vous
  2333.     que certaine police système de l'utilisateur ne modifieront pas votre
  2334.     mise en page.
  2335.     - taille = 8 ou 9
  2336.  
  2337.  
  2338. 9F. fonctions de support du système
  2339. -----------------------------------
  2340.  
  2341. bool:=KickVersion(vers)
  2342.  
  2343.     retourne TRUE si le Kickstart de la machine est égal ou supérieur à
  2344.     <vers>, sinon FALSE
  2345.  
  2346.  
  2347. mem:=New(n)
  2348.  
  2349.     créé dynamiquement un tableau (ou un espace mémoire, si vous voulez) de
  2350.     <n> octets. La différence avec AllocMem() est que l'appel se fait
  2351.     automatiquement avec un dreapeau de $10000 et que vous n'avez pas à
  2352.     appeler Dispose(), car lié à une liste mémoire qui est automatiquement
  2353.     désallouée à la sortie du programme.
  2354.  
  2355.  
  2356. Dispose(mem)
  2357.  
  2358.     gèle n'importe quelle <mem> alloué par New(). Vous ne devez utiliser cette
  2359.     fonction que si vous voulez libérer explicitement de la mémoire _pendant_
  2360.     que la programme tourne, tout comme cela se fait à la sortie de celui-ci.
  2361.  
  2362.  
  2363. CleanUp(valeur_retournée)
  2364.  
  2365.     sort du programme à n'importe quel moment. Il remplace la fonction DOS
  2366.     Exit() : n'utilisez jamais celui-là ! plutôt CleanUp(), qui permet de
  2367.     désallouer la mémoire, de fermer correctement les bibliothèques, etc.
  2368.     La <valeur_retournée> est donnée au DOS comme code de retour (returncode).
  2369.  
  2370.  
  2371. espace:=FreeStack()
  2372.  
  2373.     retourne l'espace libre de la pile. Cela doit toujours être 1000 ou plus.
  2374.     Voir le chapitre 'implémentation' sur comment le E organise sa pile.
  2375.     Si vous n'avez pas de trop grosses récursions, vous n'avez pas à vous en
  2376.     faire quant à cet espace libre.
  2377.  
  2378.  
  2379. bool:=CtrlC()
  2380.  
  2381.     retourne TRUE si Ctrl-C est pressé depuis la dernière fois, sinon FALSE.
  2382.     Cela ne marche que pour les programmes lancés via le shell (des programmes
  2383.     CLI).
  2384.  
  2385.  
  2386. Exemple montrant comment les 3 dernière fonctions peuvent être utilisées :
  2387.  
  2388.     /* calcule le factoriel de l'argument de la ligne de commande */
  2389.  
  2390.     OPT STACK=100000
  2391.  
  2392.     PROC main()
  2393.       DEF num,r
  2394.       num:=Val(arg,{r})
  2395.       IF r=0
  2396.         WriteF('mauvais args.\n')
  2397.       ELSE
  2398.         WriteF('résultat: \d\n',fac(num))
  2399.       ENDPROC
  2400.     ENDPROC
  2401.  
  2402.     PROC fac(n)
  2403.       DEF r
  2404.       IF FreeStack()<1000 OR CtrlC() THEN CleanUp(5)    /* vérif suppl */
  2405.       IF n=1 THEN r:=1 ELSE r:=fac(n-1)*n
  2406.     ENDPROC r
  2407.  
  2408. Bien sûr, cette récursion marchera difficilement avec peu de pile, et quand il
  2409. marche, il est stoppé si vite par FreeStack() que vous n'aurez pas le temps
  2410. de presser Ctrl-C, mais l'idée est là.
  2411. Une définition de fac(n) comme suit est moins sûre :
  2412.  
  2413.     PROC fac(n) RETURN IF n=1 THEN 1 ELSE fac(n-1)*n
  2414.  
  2415.  
  2416. 9G. mathématiques et autres fonctions
  2417. -------------------------------------
  2418.  
  2419. a:=And(b,c)
  2420. a:=Or(b,c)
  2421. a:=Not(b)
  2422. a:=Eor(b,c)
  2423.  
  2424.     Ceux-ci marchent comme les opérations usuelles, aussi bien booléennes
  2425.     qu'arithmétiques.
  2426.     Notez que pour And() et Or(), un opérateur existe.
  2427.  
  2428.  
  2429. a:=Mul(b,c)
  2430. a:=Div(a,b)
  2431.  
  2432.     réalise les mêmes opérations que les opérateurs '*' et '/', mais
  2433.     maintenant en vrai 32 bits. Pour des raisons de rapidité, les opérations
  2434.     normale sont faites en 16 bits * 16 bits = 32 bits et 32 bits / 16 bits
  2435.     = 16 bits. C'est suffisent pour quasiment tous les calculs, et quand ce
  2436.     n'est pas le cas, utilisez Mul() et Div().
  2437.     NOTE : pour Div(), a est divisé par b, pas l'inverse.
  2438.  
  2439.  
  2440. bool:=Odd(x)
  2441. bool:=Even(x)
  2442.  
  2443.     retourne TRUE ou FALSE si x est impaire (Odd) ou paire (Even)
  2444.  
  2445.  
  2446. num:=Rnd(max)
  2447. seuil:=RndQ(seuil)
  2448.  
  2449.     Rnd() donne un nombre au 'hasard' à partir d'un seuil allant de 0 à max-1.
  2450.     Par exemple, Rnd(1000) retourne un entier entre 0 et 999.
  2451.     Pour initialiser le seuil interne, appelez Rnd() avec un nombre négatif.
  2452.     la valeur absolue de cette valeur sera le seuil initial.
  2453.  
  2454.     RndQ() calcul un nombre au 'hasard' plus vite (Quicker) que Rnd(), mais
  2455.     retourne un nombre sur 32 bits. Utilisez le résultat comme seuil pour le
  2456.     prochain appel, et pour seuil de départ, utilisez un grande valeur, comme
  2457.     $A6F87EC1.
  2458.  
  2459.  
  2460. valeur_abs:=Abs(valeur)
  2461.  
  2462.     calcule la valeur absolue.
  2463.  
  2464.  
  2465. a:=Mod(b,c)
  2466.  
  2467.     divise b (32bits) par c(16bits) et retourne le modulo a (16bits)
  2468.  
  2469.  
  2470. x:=Shl(y,n)
  2471. x:=Shr(y,n)
  2472.  
  2473.     déplace y de n bits vers la gauche (Shl) ou vers la droite (Shr)
  2474.  
  2475.  
  2476. a:=Long(adr)
  2477. a:=Int(adr)
  2478. a:=Char(adr)
  2479.  
  2480.     lit (peek) la mémoire à l'adresse <adr>, et retourne la valeur trouvée.
  2481.     Ces fonctions travaillent avec respectivement des valeurs de 32, 16 et 8
  2482.     bits. Notez que le compilateur ne vérifie pas si l'<adr> est valide. Ces
  2483.     fonctions sont implementées en E pour les cas où écrire ou lire la mémoire
  2484.     par des pointeur (PTR TO <type>) demanderait une programmation complexe,
  2485.     voire moins bonne.
  2486.     Vous n'êtes pas encouragé à utiliser ces fonctions.
  2487.  
  2488.  
  2489. PutLong(adr,a)
  2490. PutInt(adr,a)
  2491. PutChar(adr,a)
  2492.  
  2493.     écrit (poke) la valeur <a> à l'adresse <adr> en mémoire.
  2494.     Voir : Long()
  2495.  
  2496.  
  2497. 9H. fonctions liants les chaines, les listes
  2498. --------------------------------------------
  2499.  
  2500. Le E propose un ensemble de fonctions qui permettent la création de listes
  2501. liées (linked) avec les types de données STRING et LIST, ou chaines et
  2502. listes qui sont créés avec String() et List(). Comme vous devez le savoir
  2503. maintenant, les chaines et les listes sont des pointeurs sur leurs données
  2504. respectives, et ont des champs suppléméntaires d'offsets négatifs décrivant
  2505. leur longueur actuelle et leur longueur maximale. Ces offsets dont PRIVÉs.
  2506. Ajouté à ces 2 champs, n'importe quel type de donnée complexe, a un champ
  2507. 'next' (suivant), égal à NIL par défaut, qui peut servir à construire une
  2508. liste de chaines liées (linked), par exemple.
  2509. Dans la suite, j'utiliserai le terme 'complexe' pour signifier un pointeur
  2510. sur une chaine ou une liste, et 'queue' (tail) pour signifier un tel pointeur
  2511. ou un qui a déja d'autres chaines liées à lui. 'queue' peut alors être un
  2512. pointeur NIL, ce qui signifie la fin de la liste.
  2513.  
  2514.  
  2515. complexe:=Link(complexe,queue)
  2516.  
  2517.     mets la valeur <queue> dans le prochain champ de <complexe>. Retourne de
  2518.     nouveau <complexe>.
  2519.     Exemple :
  2520.  
  2521.         DEF s[10]:STRING, t[10]:STRING
  2522.         Link(s,t)
  2523.  
  2524.     crée une liste liée comme : s --> t --> NIL
  2525.  
  2526.  
  2527. queue:=Next(complexe)
  2528.  
  2529.     lit le champ suivant de la variable <complexe>. Cela peut être bien sûr
  2530.     NIL, ou une liste liées entière. Appeler Next(NIL) donnera NIL, il est
  2531.     donc prudent d'appeler Next() si vous n'êtes pas sûr que vous êtes à la
  2532.     fin de la liste liée.
  2533.  
  2534.  
  2535. queue:=Forward(complexe,n)
  2536.  
  2537.     pareil que Next(), seulement avance de n liens, au lieu d'un seul, donc :
  2538.  
  2539.         Next(c) = Forward(c,1)
  2540.  
  2541.     Vous pouvez sans crainte appeler Forward() avec n trop grand, la fonction
  2542.     s'arrètera si elle rencontre NIL pendant la recherche de liens, et
  2543.     retournera NIL.
  2544.  
  2545.  
  2546. DisposeLink(complexe)
  2547.  
  2548.     fait de même que Dispose(), avec 2 différences : la fonction ne marche
  2549.     qu'avec les chaines et listes allouées par String() et List(), et
  2550.     désallouera automatiquementla queue du complexe aussi.
  2551.     Notez que de grandes listes liées contenant des chaines alouées par
  2552.     String(), tout comme celles allouée localement ou globalement avec
  2553.     STRING, doivent être désallouée de cette façon.
  2554.  
  2555. Pour un bon exemple de comment des listes liées de chaines peuvent être
  2556. utilisé, voir le programme 'D.e'
  2557.  
  2558.  
  2559. 9I. cellule lisp et fonctions cellulaires
  2560. -----------------------------------------
  2561.  
  2562.     a) Définition :
  2563.        ----------
  2564.  
  2565. Ouaip. C'est vrai. Vous pensiez que le LISP c'était chouette, ben, essayez le
  2566. E maintenant. [Ou bien : l'histoire de pourquoi le E est un meilleur LISP que
  2567. le LISP même :-)]
  2568.  
  2569. A partir de la v3, le E possède les type de donnée cellulaire ('cell
  2570. datatype'), quasi identique aux cellules du langage LISP. D'un point de vue
  2571. technique, E a:
  2572.  
  2573. `Conservative Mark and Sweep Garbage-Collected Lisp-Cells'
  2574.  
  2575. Simplement, cela lui permet d'être capable d'allouer des cellules LISP qui
  2576. sont des paires de 2 valeurs.
  2577.  
  2578.         x:=<a,b>
  2579.  
  2580. ce qui est mieux que NEW [a,b]:LONG, seulement maintenant le E désallouera
  2581. les 8 octets en question lui-même lorsqu'il aura besoin de mémoire et qu'aucun
  2582. pointeur n'y pointe. En pratique, cela signifie que vous pouvez avoir des
  2583. fonctions qui crée des cellules tampons sans vous soucier de les libérer. Et
  2584. tout programmeur en LISP sera capable de vous expliquer qu'avec des cellules,
  2585. vous pouvez construire n'importe quelle structure de donnée (et en
  2586. particulier des arbres et des listes).
  2587. [Note: ce texte n'explique pas comment faire pour utiliser complètement les
  2588. cellules, car des douzaines de livres sur le LISP on été écrit à ce propos].
  2589.  
  2590. Choisir des valeurs peut être facilement fait grace à Car(x) et Cdr(x), 2
  2591. fonctions LISP qui prenne la tête ('head') et la queue ('tail') (premier et
  2592. second) élément de la cellule. Si x est un PTR TO LONG, même x[0] et x[1] sont
  2593. permis.
  2594.  
  2595. On peut aussi écrire des listes de cellules
  2596.  
  2597.         <a,b,c>
  2598.  
  2599. (notez les virgules) étant le raccourcit de
  2600.  
  2601.         <a:<b:<c:NIL>>>
  2602.  
  2603. Une alternative à Car/Cdr est l'unification E:
  2604.  
  2605.         x <=> <a,b:c>
  2606.         a+b+c
  2607.  
  2608. au lieu de:
  2609.  
  2610.         Car(x)+Car(Cdr(x))+Cdr(Cdr(x))
  2611.  
  2612. L'unification cellulaire du LISP ressemble à l'unification des listes E.
  2613. (voir 4L)
  2614. Par exemple:
  2615.  
  2616.         x <=> <1,2|a>
  2617.  
  2618. est équivalent à:
  2619.  
  2620.         IF Car(x)=1
  2621.           IF Car(Cdr(x))=2
  2622.             a:=Cdr(Cdr(x))
  2623.             ...
  2624.  
  2625.  
  2626. Une valeur nulle LISP est possible "<>", qui est égal à NIL et 0.
  2627.  
  2628. Certaines fonctions sont possibles (notez que Cons() n'est _seulement_ possible
  2629. avec <...>).
  2630.  
  2631.     b) Fonctions :
  2632.        ---------
  2633.  
  2634. h:=Car(c)       t:=Cdr(c)
  2635.  
  2636.     fixe la tête ('head') et la queue ('tail') de la cellule c
  2637.  
  2638. bool:=Cell(c)
  2639.  
  2640.     donne l'état de c, si elle pointe ou non sur une cellule, donc
  2641.     Cell(<1>)=TRUE, et Cell(3.14)=FALSE. Ce n'est pas une fonction rapide.
  2642.  
  2643. n:=FreeCells()
  2644.  
  2645.     retourne la quantité de cellule libre possible. C'est une fonction très
  2646.     lente. Il ne devrait y avoir besoin d'appeler cette fonction, sinon par
  2647.     curiosité.
  2648.  
  2649. SetChunkSize(k)
  2650.  
  2651.     Fixe la taille des chunks pour allouer k kilooctets pour les cellules. Le
  2652.     défaut est de 128 Ko. Cett fiction nepeut être appeler qu'une seule fois,
  2653.     et seulement avant que la première allocation soit faites. Après, la
  2654.     fonction n'a aucun effet.
  2655.  
  2656. En général; prenez un bon bouquin sur le LISP pour mieux comprendre comment
  2657. utiliser les cellules.
  2658.  
  2659. On peut écrire n'importez quelle fonctions LISP en E, avec éxactement la même
  2660. fonctionnalité:
  2661.  
  2662.     PROC append(x,y) IS IF x THEN <Car(x)|append(Cdr(x),y)> ELSE y
  2663.     PROC nrev(x) IS IF x THEN append(nrev(Cdr(x)),<Car(x)>) ELSE NIL
  2664.     PROC sum(x) IS IF x THEN Car(x)+sum(Cdr(x)) ELSE 0
  2665.  
  2666. Utiliser une implementation destructive pour des fonctions comment celles-là
  2667. est aussi possible.
  2668.  
  2669.     c) De la technique :
  2670.        ---------------
  2671.  
  2672. Le 'garbage collector' implémente 'a conservative mark and sweep algorithm'
  2673. qui a été testé pour être 5 à 25 fois plus rapide que plusieurs implémentations
  2674. de langage logique et fonctionnel sur l'Amiga. Conservative signifie qu'en cas
  2675. de doute, le GC (Garbage Collector) ne désallouera pas une cellule. Ceci est
  2676. nécessaire à cause dy langage sans type tel que le E, le GC peut facilement
  2677. recontrer une valeur qui n'est pas un pointeur valide etc.
  2678.  
  2679. Le GC alloue de gros chunks (128Ko par défaut), dans lesquels il alloue des
  2680. cellules. Par manque de cellule, il cherchera de la place en regardant la pile
  2681. et les registres de pointeurs dans l'espace cellulaire, et récursivement les
  2682. marquera. Après quoi, toutes les cellules non marquées sont réutilisées, et si
  2683. le gain en cellule est petit, un nouveau chunk sera alloué.
  2684.  
  2685. Intéraction avec d'autres valeur du E:
  2686.     - sauver d'autres valeurs dans les celluels n'est pas un problême. Objets,
  2687.       chaines, flottants, n'importe quoi peut être mis dans une cellule sans
  2688.       trop importuner le GC ;
  2689.     - sauver des cellules dans d'autres valeurs, par exemple un pointeur sur une
  2690.       cellule dans un objet dynamique, est problematic, car le GC ne sera pas
  2691.       capable de le trouver là. Une solution sera trouvée. Malgré tout je pense
  2692.       que cela n'arrivera que très rarement.
  2693.       Des pointeurs sur des cellules peuvent sauvé en toute sécurité dans des
  2694.       variables globales et locales, même des registres, et n'importe quelle
  2695.       structure de donnée. [et plus important dans d'autres cellules!]
  2696.  
  2697. Caveats:
  2698.     - Le GC ne peut collecter des cellules qui ont une liste de Car >1000, ie
  2699.       <<<NIL:a>:b>:c>, mais de 100 entrées au lieu de 3 ici. Cela arrivera
  2700.       difficilement car leslistes comme celle-la sont toujours formés comme
  2701.       des listes de Cdr, que le GC peut agrandir à l'infinie.
  2702.     - le code assembleur en ligne ne doit jamais mettre dans la pile de choses
  2703.       qui se sont pas alignés sur des LONGs. Ceci était déja valable pour la
  2704.       version 2.1b, mais maintenant c'est plus qu'essentiel.
  2705.  
  2706. Il y a une différence en taille de chunk entre l'espace et le temps.
  2707. Allouer de petits chunks est bien tant que vous ne dépensez pas beaucoup de
  2708. mémoire, malgré tout, lorrs de la collection (garbage collecting), l'effort
  2709. de chaque pointeur pour tracer est proportionnel à l'espace. Pour cela :
  2710.     - si la vitesse est le plus important, mettez la taille des chunks de telle
  2711.       façon qu'un seule espace est nécessaire. Si l'utilisation maximale d'une
  2712.       cellule est de 50Ko, un chunk de 100 a 150 Ko donnera un performance
  2713.       maximale ;
  2714.     - si l'utilisation dela mémoire est le plus important, dans l'exemple
  2715.       ci-dessus, des chunks de 20Ko ou 30Ko sera optimal pour la mémoire.
  2716.  
  2717. En général, calculer le temps d''utilisation maximal de votre algorythme
  2718. cellulaire avec différentes tailles pour voir quelle valeur est la
  2719. meilleure.
  2720.  
  2721.  
  2722.  
  2723. +---------------------------------------------------------------+
  2724. |               10. FONCTIONS DE BIBLIOTHEQUES ET MODULES       |
  2725. +---------------------------------------------------------------+
  2726.  
  2727.  
  2728. 10A. appels de bibliothèque prédéfinis (built-in)
  2729. -------------------------------------------------
  2730.  
  2731. Comme vous l'avez remarqué dans les sections précédentes, le morceau de code
  2732. lié (linked) automatiquement au début de votre source, appelé 'code
  2733. d'initialisation', ouvre toujours les 4 bibliothèques Intuition, Dos, Graphics,
  2734. Mathffp, et à cause de ça, le compilateur possède tous les appels des 5
  2735. bibliothèques (avec l'exec) (il y en a une petite centaine).
  2736. Ces appels sont valables jusqu'au workbench 2.04. Ceux du système 3.0 devrait
  2737. être inclus dans la prochaine version d'Amiga E.
  2738. Exemple, pour appeler la fonction Open(), de la bibliothèque Dos, écrivez :
  2739.  
  2740.     gestion:=Open('mon_fichier',OLDFILE)
  2741.  
  2742. ou AddDisplayInfo() de la bibliothèques graphics :
  2743.  
  2744.     AddDisplayInfo(mes_info)
  2745.  
  2746. Aussi simple que ça !
  2747.  
  2748.  
  2749. 10B. interfacer le système Amiga avec les modules v39
  2750. -----------------------------------------------------
  2751.  
  2752. Pour utiliser d'autres bibliothèques que les 5 décrites dans la section
  2753. précédente, vous avez besoin de modules. Aussi, si vous voulez utiliser des
  2754. objet (OBJECT) ou des constantes (CONST) d'includes utilisé en C ou en
  2755. Assembleur, vous vew besoin de modules.
  2756. Les modules sont des fichiers binaires qui peuvent inclure des définitions de
  2757. constantes, d'objets, de bibliothèques et de fonction. L'avantage que les
  2758. modules soient compilées, par rapport à des fichiers ASCII, est qu'ils n'ont
  2759. pas besoin d'être recompilé encore et encore, chaque fois que votre programme
  2760. est compilé. Le désavantage est qu'ils ne peuvent pas être facilement être
  2761. visualisés ; ils ont besoin d'utilitaires comme ShowModule (voir 17A) pour les
  2762. rendre visible.
  2763. Les modules contenant les définitions de bibliothèque (les appels) sont dans
  2764. le répertoire racine de emodules: (le répertoire de module de la distribution)
  2765. Les définitions des constantes/objets sont dans les sous-répertoires,
  2766. structurés comme les modules originaux de Commodore.
  2767.  
  2768. syntaxe:         MODULE <nom_module>,...
  2769.  
  2770. charge un module. Utiliser les modules vous permet d'utiliser des bibliothèques
  2771. et des fonctions alors inconnus du compilateur (et du système).
  2772.  
  2773. Exemple : un raccourcit du programme 'source/examples/asldemo.e' qui utilise
  2774. des modules pour afficher une boites de requête de fichier (filerequester), de
  2775. la bibliothèque Asl.library du système 2.0.
  2776.  
  2777.     MODULE 'Asl', 'libraries/Asl'
  2778.  
  2779.     PROC main()
  2780.       DEF req:PTR TO filerequestr
  2781.       IF aslbase:=OpenLibrary('asl.library',37)
  2782.         IF req:=AllocFileRequest()
  2783.           IF RequestFile(req) THEN WriteF('File: "\s" in "\s"\n',
  2784.                                           req.file,req.dir)
  2785.           FreeFileRequest(req)
  2786.         ENDIF
  2787.         CloseLibrary(aslbase)
  2788.       ENDIF
  2789.     ENDPROC
  2790.  
  2791.  
  2792. Du module 'asl', le compilateur prend les définitions des fonctions de l'asl
  2793. comme RequestFile(), et la variable globale 'aslbase', qui doit seulement être
  2794. initialisée par le programmeur.
  2795. Du module 'libraries/asl', il prend la définition de l'objet de la boite de
  2796. requête de fichier (filerequester), qu'on utilise pour lire le fichier choisit
  2797. par l'utilisateur.
  2798. Alors, ce n'était pas trop dur de programmer une boite de requête en E ?
  2799.  
  2800.  
  2801. 10C. compiler ses propres modules
  2802. ---------------------------------
  2803.  
  2804. Avec la v3, vous pouvez réunir tous les PROCs, CONSTs, OBJECTs et quelques
  2805. variables globales que vous sentez qu'ils appartiennent au même source,
  2806. écrivez "OPT MODULE" pour signaler à EC qu'il doit être un module, et doit
  2807. être compiler en fichier .m pour être utilisé dans un programme principal,
  2808. tout comme vous le faisiez avec les 'vieux' modules.
  2809.  
  2810. Par défaut, tous les éléments d'un module sont PRIVÉS, ie non accessible
  2811. au code qui importe le fichier .m. Pour montrer les éléments que vous voulez
  2812. être visible dans le module, écrivez EXPORT devant:
  2813.  
  2814.     EXPORT ENUM TEST,UN,DEUX,TROIS,QUATRE
  2815.  
  2816.     EXPORT DEF variable_globale_importante, bla:PTR TO x
  2817.  
  2818.     EXPORT OBJECT x
  2819.       suivant,index, terme
  2820.     ENDOBJECT
  2821.  
  2822.     EXPORT PROC truc()
  2823.       /* n'importe quoi */
  2824.     ENDPROC
  2825.  
  2826. "EXPORT" est utile pour faire la distinction entre privé et public,
  2827. spécialement quand toutes les fonctions d'un OBJEcT peuvent être accessible
  2828. par PROCs, vous pouvez avoir envie de garder des OBJEcTs privé comme méthode
  2829. effective pour chacher des données (data hiding). Plus sur ce sujet, voir 14C.
  2830.  
  2831. Si dans un module _tous_ les éléments ont besoin d'être exporté (par exemple
  2832. un avec uniquement des constantes), un 'OPT EXPORT' exportera tout, sans
  2833. avoir besoin de les déclarer individuellement par EXPORT.
  2834.  
  2835. Les variables globales demande une attention particulière:
  2836.     - essayez d'éviter un tas de variables globales. Cela ajoute du désordre à
  2837.       votre projet et le rend sensible aux erreurs ;
  2838.     - les globales dans un module ne peuvent pas être initialisée directement
  2839.       dans la déclaration DEF (la raison est expliqué plus bas). Par exemple:
  2840.         DEF a             pas     DEF a=1
  2841.         DEF a:PTR TO x    pas     DEF a[10]:ARRAY OF x
  2842.     - les globales dans un module qui ne sont pas exportées fonctionnent comme
  2843.       des locales pour le module, ie ils n'y aura pas de conflit avec les
  2844.       globales d'autres modules. Celles qui _sont_ exportées sont combinés avec
  2845.       les autres, ie si dans le programme principale et les autres modules
  2846.       une variable avec le même nom est utilisée, ce sera une et même variable.
  2847.       C'est pourquoi on peut écrire DEF a[10]:ARRAY OF x dans le programme
  2848.       principale, et EXPORT DEF a:PTR TO x dans le module, pour partager le
  2849.       tableau. Aussi, si les 2 utilisent par exemple 'gadtools.m', uniquement
  2850.       un des 2 a besoin d'initialiser 'gadtoolsbase' pour les 2 pour pouvoir
  2851.       faire un appel de la bibliothèque. Si vous ne voulez pas que la base de
  2852.       la bibliothèque soit partagé (ie vous voulez avoir une base de
  2853.       bibliothèque locale et privée), simplement redéclarez le dans un DEF
  2854.       qui n'est pas EXPORTé. Si vous exportez une variable d'une manière
  2855.       générale d'un module, donnez lui un chouette petit nom unique.
  2856.     - utiliser des globales dans des modules qui propose des types de données
  2857.       générales demende un peu d'attention. Le module peut être utilisé par
  2858.       plus d'un autre module, dans lesquels il peut être difficile de
  2859.       connaitre à qui appartient telles ou telles variables. Faites bien
  2860.       attention à cela.
  2861.  
  2862. Utiliser des modules dans des modules.
  2863.     Cela demande (encore) un peu d'attention. Soi le module (B) que vous
  2864.     incluez dans votre propre module (A) ne déclare que des CONSTs,
  2865.     bibliothèques (LIBRARY) et OBJEcTs (sans code) rien de spéciale ne se
  2866.     passe, mais si B inclue des PROCs, alors il est évident que ce code devra
  2867.     être linké plus tard. Ainsi si un programme principal utilise A, B devra
  2868.     être présent pour le compilation. Le fait que A aie besoin de B, est sauvé
  2869.     dans A, et peut être visualisé avec ShowModule. Ce type d'utilisation peut
  2870.     grossir et donner un arbre de dépendance, ce qui a pour résultat suivant,
  2871.     si vous utilisez un module dans votre programme, un tas d'autre sont
  2872.     automatiquement linké à lui. Ainsi, le système de module E garde
  2873.     automatiquement des traces des dépendances alors que d'autres langages ont
  2874.     besoin d'un makefile. EC permet aussi des inclusions circulaires, et
  2875.     charge/linke des modules au plus une fois (ie, ne linke pas des modules
  2876.     inutilisés).
  2877.  
  2878.  
  2879. Essayez le nouveau ShowModule (voir 17A) pour voir ce que EC met dans les
  2880. modules.
  2881.  
  2882. Inclure des modules d'autres répertoires.
  2883.     Par défaut, un nom de module est préfixé par 'emodules:' pour obtenir le
  2884.     fichier actuel. Maintenant vous pouvez préfixer le nom avec un '*' pour
  2885.     donner le répertoire où le source se trouve, donc:
  2886.  
  2887.         MODULE 'chose', '*chose'
  2888.  
  2889.     Si cette déclaration était dans le source 'WORK:E/truc.e', ces 2 modules
  2890.     seraient 'emodules:chose.m' et 'WORK:E/chose.m'.
  2891.  
  2892. C'est le voie normale d'inclure des parties de votre application dans d'autres
  2893. parties. Si vous écrivez des modules que vous utilisez dans plusieurs
  2894. programmes, il seraient pratique de les archiver dans une hiérarchie de
  2895. modules E, et la place pour ça est le répertoire 'emodules/other/'.
  2896.  
  2897.  
  2898.  
  2899. 10D. le module cache
  2900. --------------------
  2901. (voir 17D, ShowCache/FlushCache à ce propos).
  2902.  
  2903.  
  2904.  
  2905. +---------------------------------------------------------------+
  2906. |                    11. EXPRESSIONS COTÉES                     |
  2907. +---------------------------------------------------------------+
  2908.  
  2909.  
  2910. 11A. les cotes (quotes) et analyse (scope)
  2911. ------------------------------------------
  2912.  
  2913. Les expressions cotées commence avec une apostrophe inverse `. La valeur
  2914. d'une expressions cotées n'est pas le résultats d'un calcul d'une expression,
  2915. mais l'adresse du code. Le résultat peut être passé à une variable normale, ou
  2916. comme argument de certaines fonctions.
  2917. Exemple:
  2918.  
  2919.     mafonc:=`x*x*x
  2920.  
  2921. mafonc est maintenant un pointeur sur une fonction qui calcule x^3 quand elle
  2922. est évaluée. Ces pointeurs de fonctions sont très différents des procédures
  2923. normales et ne doivent jamais être mélangées. Les plus grandes différences
  2924. sont qu'une expression cotée est une simple expression, et donc, ne peut pas
  2925. avoir sa propre variable locale. Dans notre exemple, 'x' est juste une variable
  2926. locale ou globale. C'est là que nous devons être prudent :
  2927. Si on évalue mafonc plus tard dans la même procédure, 'x' doit être local,
  2928. mais si mafonc est donné comme paramètre à une autre procédure, et puis
  2929. évauluée, 'x' doit être global. Il n'y a aucune vérification du compilateur.
  2930.  
  2931.  
  2932. 11B. Eval(fonc)
  2933. ---------------
  2934.  
  2935. évalue simplement une expressions cotées (exp = Eval(`exp)).
  2936.  
  2937. NOTE : parce que le E est un langage peu typé, écrire accidentellement
  2938. 'Eval(x*x)' au lieu de 'Eval(`x*x) ne sera pas remarqué par le compilateur,
  2939. et vous donnera beaucoup de problême : la valeur de x*x sera utilisé comme
  2940. pointeur à coder.
  2941.  
  2942. Pour comprendre pourquoi les 'expressions cotées' sont un atout puissant,
  2943. pensez au cas suivant :
  2944.  - if vous voulez réaliser un ensemble d'actions suivant un ensemble de
  2945. variables, vous devez normalement écrire une fonction, et l'appeler avec
  2946. différents arguments. Mais que ce passe-t-il si l'élément que vous voulez
  2947. passer tout un code ? Dans les langages traditionnels, c'est impossible.
  2948. Pas en E.
  2949. Exemple : supposons quez vous voulez écrire un programme qui compte le temps
  2950. éxécution de différentes expressions. En E, on écrire :
  2951.  
  2952.     PROC timing(fonc,titre)
  2953.       /* faites plein de chose pour définir le temps */
  2954.       Eval(fonc)
  2955.       /* et le reste */
  2956.       WriteF('temps mesuré pour \s est \d\n',titre,t)
  2957.     ENDPROC
  2958.  
  2959. et appelez le avec :
  2960.  
  2961.     timing(`x*x*x,'multiplication')
  2962.     timing(`sizycalc(),'gros calcul')
  2963.  
  2964.  
  2965. dans d'autres langages, vous devez avoir des copies de 'timing()' pour
  2966. chaque appel, ou vous devez mettre chaque expression dans une fonction
  2967. séparé.
  2968.  
  2969. Un autre exemple simple : pensez à ce que vous pouvez faire avec des
  2970. structures de données (listes) rempli de code non évalué :
  2971.  
  2972.     tracefonc:=[`Plot(x,y,c),`Line(x,y,x+10,y+10,c),`Box(x,y,x+20,y+20,c)]
  2973.  
  2974. Notez que l'idée de fonctions comme des variables/valeurs normales n'est pas
  2975. nouvelles en E. Les expressions cotées viennent litéralement du LISP, qui
  2976. possède la fonction encore plus puissante appelé Lambda, qui peut être donnée
  2977. comme arguments à des fonctions ; les expressions cotées de E peuvent aussi
  2978. être vu comme des fonctions Lambda sans paramêtre (ou seulement avec des
  2979. paramêtres globals).
  2980.  
  2981.  
  2982. 11C. built-in functions
  2983. ----------------------
  2984.  
  2985. MapList(varadr,liste,listevar,fonc)
  2986.  
  2987.     calcule la fonction sur tous les éléments de <liste>, et retourne tous les
  2988.     résultats dans <listevar>. <func> doit être une expressions cotées (voir
  2989.     plus haut). <varadr> est donné par référence.
  2990.     Exemple :
  2991.  
  2992.         MapList({x},[1,2,3,4,5],r,`x*x)     r est alors :     [1,4,9,16,25]
  2993.  
  2994.  
  2995. ForAll(varadr,list,func)
  2996.  
  2997.     retourne TRUE si tous les éléments de la liste sont évalués par la
  2998.     fonction comme vrais, sinon FALSE. Peut être aussi utilisé pour réaliser
  2999.     une certaine fonction sur tous les éléments d'une liste :
  3000.  
  3001.         ForAll({x},['un','deux','trois'],`WriteF('exemple: \s\n',x))
  3002.  
  3003.  
  3004. Exists(varadr,list,func)
  3005.  
  3006.     Comme pour ForAll(), mais retourne TRUE si la fonction évalue au moins
  3007.     un élément de vrai (<>0).
  3008.     Notez que ForAll() évalue toujours tous les éléments, mais pas forcément
  3009.     Exist().
  3010.  
  3011. Exemple de comment utiliser ces fonctions en pratique :
  3012. on alloue differentes tailles en mémoire en une définition, les vérifie en
  3013. une seule fois, et les libère toutes, mais uniquement celles qui ont été
  3014. alouée. (v37+) :
  3015.  
  3016.     PROC main()
  3017.       LOCAL mem[4]:LIST,x
  3018.       MapList({x},[200,80,10,2500],mem,`AllocVec(x,0)) /* alloue quelques */
  3019.       IF ForAll({x},mem,`x)                            /* suxxes ? */
  3020.         WriteF('Yes!\n')
  3021.       ELSE
  3022.         WriteF('No!\n')
  3023.       ENDIF
  3024.       ForAll({x},mem,`IF x THEN FreeVec(x) ELSE NOP)   /* libère seulement */
  3025.                                                     /* ceux qui sont <>NIL */
  3026.     ENDPROC
  3027.  
  3028.  
  3029. Notez l'abscence d'itération dans ce code. Essayez de reécrire cet exemple
  3030. dans autre langage pourquoi c'est si spécial.
  3031.  
  3032.  
  3033.  
  3034. +---------------------------------------------------------------+
  3035. |                  12. SUPPORT DES NOMBRES FLOTTANTS            |
  3036. +---------------------------------------------------------------+
  3037.  
  3038.  
  3039. 12A. utiliser les flottants et les opérateurs flottants
  3040. -------------------------------------------------------
  3041.  
  3042. Surpasser les opérateurs standard + * etc, avec leurs équivalents flottants
  3043. est possible à partir du système 2.0 de l'Amiga E, mais j'ai enlevé la partie
  3044. principale de la documentation les concernant, car le concept flottant en E
  3045. changera avec les versions supérieures : ces versions vous permettra du code
  3046. inline pour 68881 pour des routines FFP, et de façon transparente.
  3047.  
  3048. Si vous voulez réellement utiliser les flottants avec la version 2.1b, vous
  3049. êtes prié d'utiliser les routines prédéfinies SpXxx() de la bibliothèque
  3050. mathffp.library.
  3051. Exemple:
  3052.  
  3053.     x:=SpMul(y,0.013483)
  3054.  
  3055. Attention quand la prochaine version sortira, votre source devra être modifié
  3056. (en mieux !).
  3057.  
  3058.  
  3059. 12B. expressions flottantes et conversion
  3060. -----------------------------------------
  3061.  
  3062. Comme 12A.
  3063.  
  3064.  
  3065.  
  3066. +---------------------------------------------------------------+
  3067. |                      13. GESTION DES ERREURS                  |
  3068. +---------------------------------------------------------------+
  3069.  
  3070.  
  3071. 13A. définition des gestion d'erreurs (HANDLE/EXCEPT)
  3072. -----------------------------------------------------
  3073.  
  3074. Le mécanisme d'exception est a peu près le même qu'en ADA ; il permet des
  3075. réactions flexibles sur les erreurs de votre programme et les opérations
  3076. de resources complexes.
  3077. NOTE : le terme d'exception' en E n'a que peut de relation avec les
  3078. exceptions venant des processeurs 680x0.
  3079.  
  3080. Une gestion d'erreur se fait par un bout de code qui sera appelé quand une
  3081. erreur survient lors du fonctionnement du programme, comme une fenêtre qui
  3082. ne s'ouvre pas, ou de la mémoire non allouée. Vous, ou le système lui-même,
  3083. dira que quelque chose ne va pas (cela s'appelle 'raising an exception' -
  3084. 'lever une exception'), alors le système cherchera le bon gestionnaire que
  3085. vous aurez programmé. Je dit 'le bon' car le programme peux avoir plusieurs
  3086. gestionnaire, à chaque niveau du programme.
  3087. Une définition de fonction normale doit (comme on le sait) ressembler à ça :
  3088.  
  3089.     PROC bla()
  3090.       /* ... */
  3091.     ENDPROC
  3092.  
  3093. Une fonction avec un gestionnaire d'exception, à ça :
  3094.  
  3095.     PROC bla() HANDLE
  3096.       /* ... */
  3097.     EXCEPT
  3098.       /* ... */
  3099.     ENDPROC
  3100.  
  3101. Le bloc entre PROC et EXCEPT est éxécuter normalement, et si aucune erreur
  3102. n'arrive, le bloc ntre EXCEPT et ENDPROC est sauté. La procédure se termine
  3103. au ENDPROC. Si une exception est levée, soit dans les partie du PROC, ou
  3104. dans n'importe quelle fonction appelée dans ce bloc, le gestionnaire
  3105. d'exception est invoqué.
  3106.  
  3107. 13B. utiliser la fontion Raise()
  3108. --------------------------------
  3109.  
  3110. Il y a beaucoup de moyens de lever une exception, la plus simple est
  3111. d'utiliser la fonction Raise() :
  3112.  
  3113.         Raise(exceptionID)
  3114.  
  3115. <exceptionID> est simplement une constante qui définie le type d'exception,
  3116. et est utilisé par les gestionnaires pour définir ce qui n'allait pas.
  3117. Exemple :
  3118.  
  3119.     ENUM NOMEM,NOFILE  /* et d'autres */
  3120.  
  3121.     PROC bla() HANDLE
  3122.       DEF mem
  3123.       IF (mem:=New(10))=NIL THEN Raise(NOMEM)
  3124.       ma_fonc()
  3125.     EXCEPT
  3126.       SELECT exception
  3127.         CASE NOMEM
  3128.           WriteF('Pas de mémoire!\n')
  3129.         /* ... et d'autres */
  3130.       ENDSELECT
  3131.     ENDPROC
  3132.  
  3133. PROC mafonc()
  3134.   DEF mem
  3135.   IF (mem:=New(10))=NIL THEN Raise(NOMEM)
  3136. ENDPROC
  3137.  
  3138. La variable 'exception' dans le gestionnaire contient toujours la valeur
  3139. de l'argument passé par la fonction Raise().
  3140. Dans les 2 cas du New(), la fonction Raise() appel le gestionnaire de la
  3141. fonction bla(), et retourne à la fonction qui a appelé.
  3142. Si ma_fonc() avait son propre gestionnaire d'exception, c'est celui là qui
  3143. serait appelé par le New() de la fonction ma_fonc(). La recherche d'un
  3144. gestionnaire se fait dès le début de la procédure où il est définit
  3145. jusqu'au EXCEPT, en incluant tous les appels fait à partir de là.
  3146.  
  3147. Cela a 3 conséquences :
  3148. A. les gestionnaires sont organisés de façon récursive. Le gestionnaire
  3149.    actuellement appelé est dépendant de la fonction appelé durant le
  3150.    fonctionnement du programme.
  3151. B. Si une exception est levée au sein d'un gestionnaire, le gestionnaire du
  3152.    niveau inférieur (le précédent) est appelé. Cette caractèristique peut
  3153.    être utilisé pour construire des schémas d'allocation de resources
  3154.    récursives complexes avec une grande facilité, comme on l'a vu rapidement.
  3155. C. Si une exception est levée à un niveau où aucun autre gestionnaire de
  3156.    niveau inférieur existe (ou dans un programme qui n'a pas du tout de
  3157.    gestionnaire du tout), le programme est arrêté (c'est à dire qu'un Raise(x)
  3158.    à le même effet qu'un CLeanUp(0)).
  3159.  
  3160.  
  3161. 13C. définition des exceptions pour les fonctions prédéfinies (RAISE/IF)
  3162. ------------------------------------------------------------------------
  3163.  
  3164. Avec les exceptions précédentes, nous nous sommes épargné le gros travail de
  3165. construction de notre propre fonction d'erreur. Mais il faut toujours faire
  3166. des vérification à chaque appel de New().
  3167.  
  3168. Le système de gestion des exceptions du E permet la définition d'exceptions
  3169. pour toutes les fonctions du E (comme New(), OpenW, etc.) et pour toutes les
  3170. fonction sur les bibliothèques (OpenLibrary(), AllocMem(), etc.) et même
  3171. celles inclues dans les moidules.
  3172.  
  3173. Syntaxe :   RAISE <exceptionId> IF <fonc> <comp> <valeur> , ...
  3174.  
  3175. La partie après RAISE peut être répétée, et séparé par une virgule ','.
  3176. Exemple:
  3177.  
  3178.     RAISE NOMEM IF New()=NIL,
  3179.           NOLIBRARY IF OpenLibrary()=NIL
  3180.  
  3181. La première ligne dit quelque chose comme : 'chaque fois qu'un appel de New()
  3182. retourne NIL, alors automatiquement, lève l'exception NOMEM'.
  3183. <comp> est l'un de ces symboles = <> > < >= <=
  3184. Après cette défnition, vous pouvez écrire votre programme :
  3185.  
  3186.     mem:=New(taille)
  3187.  
  3188. sans avoir à écrire :
  3189.  
  3190.     IF mem=NIL THEN Raise(NOMEM)
  3191.  
  3192. Notez que la seule différence est que <mem> ne recoit alors aucune valeur
  3193. si le gestionnaire est appelé : le code est généré pour tous les appels de
  3194. New(), vérifie directement après la fin de l'éxécution de New() et appelle
  3195. Raise() si névessaire.
  3196.  
  3197. Nous allons implémenter un petit exemple qui serait difficile à résoudre
  3198. sans gestion d'exceptions : on appel une fonction récursivement, et dans
  3199. chacune on alloue une resource (dans notre cas, de la mémoire), que l'on
  3200. alloue avant, et que l'on libère après l'appel récursif. Que se passe-t-il
  3201. si une erreur survient quelque part loin dans la récursion ; doit-on quitter
  3202. le programme? Oui : dans un langage conventionnel, on ne pourrait pas libérer
  3203. les ressources plus bas dans la récursion en sortant du programme, car tous les
  3204. pointeurs sur cette mémoire sont sauvés dans des variables locales impossibles
  3205. à atteindre. En E, on n'a seulement qu'à lever une exception, appelant
  3206. récursivement tous les gestionnaires et libérant toutes les ressources.
  3207. Exemple :
  3208.  
  3209.     CONST SIZE=100000
  3210.     ENUM NOMEM  /* ,... */
  3211.  
  3212.     RAISE NOMEM IF AllocMem()=NIL
  3213.  
  3214.     PROC main()
  3215.       alloc()
  3216.     ENDPROC
  3217.  
  3218.     PROC alloc() HANDLE
  3219.       DEF mem
  3220.       mem:=AllocMem(SIZE,0)         /* regarde combien de bloc peuvent */
  3221.                                     /* être alloué */
  3222.       alloc()                       /* fait la récursion */
  3223.       FreeMem(mem,SIZE)             /* on n'ira jamais jusqu'ici */
  3224.     EXCEPT
  3225.       IF mem THEN FreeMem(mem,SIZE)
  3226.       Raise(exception)              /* appelle récursivement tous les */
  3227.                                     /* gestionnaires */
  3228.     ENDPROC
  3229.  
  3230.  
  3231. C'est bien sûr une simulation d'un problême de programmation courant qui est
  3232. beaucoup plus complexe, et la nécessité d'une gestion d'exceptions devient
  3233. évidente. Pour un exemple concret de programme où une gestion d'erreur serait
  3234. serait très difficile sans gestion d'exception, voir l'utilitaire 'D.e'.
  3235.  
  3236.  
  3237. 13D. utilisation des identificateurs d'exceptions (ID)
  3238. ------------------------------------------------------
  3239.  
  3240. En réalité, un identificateur d'exceptions est bien sûr une valeur de 32
  3241. bits, et vous pouvez passer pratiquement n'importe quoi à un gestionnaire
  3242. d'exception : par exemple, certains l'utilisent pour passer des descriptions
  3243. d'erreur.
  3244.  
  3245.     Raise('Ne peut pas ouvrir la "gadtools.library"!')
  3246.  
  3247. En tout cas, si vous voulez bien utiliser les exceptions, et voulez avoir la
  3248. possibilité d'utilise de futur module qui lève des exceptions non définies
  3249. par votre programme, suivez les conseils suivants :
  3250.  
  3251. - Utilisez et definissez l'ID 0 comme 'pas d'erreur'
  3252.  
  3253. - Pour des exceptions particulières, utilisez des IDs de 1 à 10000.
  3254.   Définissez les avec ENUM :
  3255.  
  3256.       ENUM OK,NOMEM,NOFILE,...
  3257.  
  3258.       (OK est égale à 0, et les suivant 1+)
  3259.  
  3260. - Les IDs de 12336 à 2054847098 sont réservés pour des exceptions courantes.
  3261.   (Ces identificateurs consistent en des lettres majuscule/minuscule de
  3262.   longueur 2, 3 ou 4, encadrés par "").
  3263.   Une exception courantes est une exception qui n'a pas besoin d'être définie
  3264.   dans votre programme, et qui peuvent être utiliser par des modules
  3265.   (incorporants aussi des fonctions) pour lever un exception :
  3266.   Par exemple, vous contruisez un ensemble de procédures qui réalisent une
  3267.   certaines tâches, et voulez lever des exceptions. Comme vous voulez utiliser
  3268.   ces fonctions dans plusieurs programmes, vous aurez du mal à coordonner les
  3269.   IDs avec le programme principal, d'autant plus dure si vous utilisez
  3270.   plusieurs ensemble de procédures, qui utilisent différents IDs pour la même
  3271.   erreur !
  3272.   C'est qu'interviennent les exceptions courantes : l'ID commun pour 'plus de
  3273.   mémoire' (out of memory) est "MEM" (avec le guillemets) : chaque
  3274.   implementation n'a qu'a appeler
  3275.  
  3276.       Raise("MEM")
  3277.  
  3278.   de n'importe quelle procedure, et le programmeur qui utilise le module
  3279.   n'a besoin que de gérer un exception qui reconnait "MEM".
  3280.  
  3281.   Les futurs modules qui contiendront des ensembles de fonctions spécifieront
  3282.   quelle exception est levée par telle procédure, et si elle prend le dessus
  3283.   sur un autre ID d' autres procédures. La tâche du programmeur qui à affaire
  3284.   aux exceptions est grandement simplifiée.
  3285.   Exemples:
  3286.  
  3287.   (système)
  3288.  
  3289.       "MEM"         plus de mémoire
  3290.       "FLOW"        (proche du) dépassement de la pile
  3291.       "^C"          arrêt par Control-C
  3292.       "ARGS"        mauvais arguments
  3293.  
  3294.   (exec/libraries)
  3295.  
  3296.       "SIG"         ne peut allouer le signal
  3297.       "PORT"        ne peut créer de messageport
  3298.       "LIB"         bibliothèque non accessible
  3299.       "ASL"         pas d' asl.library
  3300.       "UTIL"        pas d' utility.library
  3301.       "LOC"         pas de locale.library
  3302.       "REQ"         pas de req.library
  3303.       "RT"          pas de reqtools.library
  3304.       "GT"          pas de gadtools.library (pareil pour les autres)
  3305.  
  3306.   (intuition/gadtools/asl)
  3307.  
  3308.       "WIN"         impossible d'ouvrir une fenêtre
  3309.       "SCR"         impossible d'ouvrir un écran
  3310.       "REQ"         ne peut pas ouvrir une boite de requête (requester)
  3311.       "FREQ"        ne peut pas ouvrir une boite de requete de fichier
  3312.                                                             (filerequester)
  3313.       "GAD"         ne peut pas créer de gadget
  3314.       "MENU"        ne peut pas créer de menu(s)
  3315.  
  3316.   (dos)
  3317.  
  3318.       "OPEN"        ne peut pas ouvrir le fichier / le fichier n'éxiste pas
  3319.       "OUT"         problême de lecture
  3320.       "IN"          problême d'écriture
  3321.       "EOF"         fin de fichier (end of file) mal placé
  3322.       "FORM"        mauvais format d'entrée (input format)
  3323.  
  3324.   La tendance générale est aux majuscules pour les exceptions système général
  3325.   et minuscule (et melange) pour les modules spécifiques.
  3326.  
  3327. Tous les autres IDs (avec les IDs négatifs) sont réservés.
  3328.  
  3329.  
  3330.  
  3331. +---------------------------------------------------------------+
  3332. |                      14. PROGRAMMATION ORIENTEE OBJET (OO)    |
  3333. +---------------------------------------------------------------+
  3334.  
  3335.  
  3336. 14A. Les caractèristiques OO en E
  3337. ---------------------------------
  3338. Les caractèristiques décrite ici dans ce chapitre sont regroupés ensemble,
  3339. car elles constituent ce qu'on définit comme les 3 composants principaux
  3340. essentiels qui font un langage 'Orientés Objets' (ie héritage, données
  3341. cachées, polymorphisme - inheritance, data hiding, polymorphism). Malgré tout
  3342. en E, cela donne un chapitre séparé car chaque partie peut-être utilisée de
  3343. plusieurs façons avec d'autres caractèristiques du E.
  3344.  
  3345.  
  3346. 14B. héritage des objets (object inheritance)
  3347. ---------------------------------------------
  3348.  
  3349. C'est toujours ennuyant de ne pas pouvoir exprimer des dpendances entre des
  3350. OBJEcTs, ou reutiliser un code qui marche sur un OBJEcTs particulier avec un
  3351. OBEcT plus grand qui englobe le premier. L'héritage des objets vous permet
  3352. de faire cela en E. Quand vous avez un objets a:
  3353.  
  3354.     OBJECT a
  3355.       suivant, index, terme
  3356.     ENDOBJECT
  3357.  
  3358. vous pouvez faire un nouvel objet b qui possède les mêmes propriétés que a
  3359. (et est compatible avec un code pour a):
  3360.  
  3361.     OBJECT b OF a
  3362.       truc, x, machin
  3363.     ENDOBJECT
  3364.  
  3365. est équivalent à:
  3366.  
  3367.     OBJECT b
  3368.       suivant, index, terme         /* venant de a */
  3369.       truc, x, machin
  3370.     ENDOBJECT
  3371.  
  3372. Avec DEF p:b, vous ne pouvez pas directement accéder à p.truc comme d'habitude,
  3373. mais aussi p.suivant.
  3374.  
  3375. Comme exemple, si l'un avait un module avec un OBJEcT pour implémenter un
  3376. certain type de donnée (par exemple une liste doublement linkée), et des PROCs
  3377. pour les supportés, on peut simplement en hériter, ajouter des données à
  3378. l'objet, et utilise les fonctions _éxistantes_ pour manipuler la liste.
  3379. Toutefois, c'est à combiner avec les méthodes (décrites plus bas), l'héritage
  3380. peut montrer sa réelle puissance.
  3381.  
  3382.  
  3383. 14C. cacher des données (data hiding) (EXPORT/PRIVATE/PUBLIC)
  3384. -------------------------------------------------------------
  3385.  
  3386. Le E a un moyen très pratique pour cacher des données. D'autres langages, comme
  3387. le C++, utilise le datahiding sur les classes, qui lève la nécessité de
  3388. 'kludges' (comme les 'friends'), et rend le 'datahiding' peu sûr (Eiffel).
  3389. Le 'datahiding' du E marche au niveau des module, qui peu modèliser le
  3390. datahiding au niveau des classes, mais aussi permet des schemas plus
  3391. intelligent.
  3392.  
  3393. PRIVATE (privé) et PUBLIC vous permet de déclarer une section d'un objet comme
  3394. visible pour le monde exterieure ou non; le monde exterieur est ici tout le
  3395. code en dehors du module. Pour le code dans un module, tout est toujours
  3396. visible.
  3397. Exemple :
  3398.  
  3399.     OBJECT mesdonnees PRIVATE                   -> tout l'objet est PRIVE
  3400.       truc:PTR TO mesdonnees, chose, grrr:INT
  3401.     ENDOBJECT
  3402.  
  3403.     OBJECT aaargh
  3404.       machin:PTR TO aaargh                      -> public
  3405.     PRIVATE
  3406.       x:INT, y:INT, z:INT                       -> privé
  3407.     PUBLIC
  3408.       bof[10]:ARRAY OF mesdonnees               -> de nouveau public
  3409.     ENDOBJECT
  3410.  
  3411.  
  3412. Un objet est par défaut public, l'ajout de PRIVATE ou de PUBLIC sert
  3413. d'interrupteur sur la visibilité des objets. Dans le premier objet, tout est
  3414. privé. Le deuxième objet n'a que (x,y,z) de privé.
  3415. PRIVATE et PUBLIC peuvent être mis:
  3416. - dans la ligne d'entête des objets,
  3417. - comme un ligne à part entière dans la définition de l'objet,
  3418. - avant les déclarations dans une définition d'objet,
  3419. (en fait virtuellement n'ilporte où).
  3420.  
  3421. Pourquoi cacher des données ?
  3422.  
  3423.     Si vous voulez savoir pourquoi le 'datahiding' est une bon moyen, vous
  3424.     aurez à lire un bon livre sur l'OO (Orientation Objet). Mais en résumé:
  3425.     on remarque qu'un tas de problêmes dans la maintenance et l'amélioration
  3426.     de grandes parties de programmes viennent du fait qu'il est dur de changer
  3427.     des choses parce que du code dépend certaines structures de données dans
  3428.     votre programme. Si vous cachez un objet, seulement le code dans un module
  3429.     dépendra du format d'un objet (par exemple changer l'implémentation de la
  3430.     pile d'un tableau (ARRAY) en une liste liée (linked list)) et le code qui y
  3431.     va. Si du code d'un grande application dépend du fait que la pile est un
  3432.     tableau (ARRAY), vous ne pourrez pas simplement le changer.
  3433.     D'un manière générale, essayez de cacher des données le plus possible sans
  3434.     devenir trop restrictif sur l'utilisation de votre objet. Utiliser les
  3435.     méthodes (methods) (voir plus bas) vous permettra souvent de garder tout
  3436.     l'objet privé.
  3437.  
  3438.  
  3439. 14D. méthodes et méthodes virtuelles
  3440. ------------------------------------
  3441.  
  3442. Une méthodes ressemble à un PROC, seulement maintenant il est un partie d'un
  3443. objet. Il vous permet d'exploiterle polymorsphisme dans les objets, come nous
  3444. le verrons plus bas.
  3445. Définition d'un méthode:
  3446.  
  3447.     OBJECT chose PRIVATE
  3448.       x:PTR TO chose, y:INT, z
  3449.     ENDOBJECT
  3450.  
  3451.     PROC getx() OF chose IS self.x
  3452.  
  3453.  
  3454. Le 'OF chose' dit au compilateur qu'il appartient à l'objet 'chose'.
  3455. Notez qu'à part le 'OF', la syntaxe est identique à un PROC, cependant, il ne
  3456. peut être appelé comme une fonction, et donc fonctionne un peu différement.
  3457.  
  3458. 'self' est un variable locale qui est accessible dans chaque méthode, et est
  3459. un pointeur sur l'objet auquel la méthode appartient (dans le cas présent,
  3460. 'self:PTR TO chose'). Cette fonction retourne juste la valeur du champ x de
  3461. chose, qui donne son sens, ce qui vous laisse la possibilité de changer ce que
  3462. représente x.
  3463.  
  3464. On peut appeler les méthodes de la même façon que les objets avec ".":
  3465.  
  3466.     DEF a:PTR TO blerk
  3467.     NEW a
  3468.     ...
  3469.     a.getx()           -> appelle la méthode getx() sur l'objet a
  3470.  
  3471. Dans cet exemple, à l'invocation, 'a' reçoit la valeur de 'self' pendant
  3472. l'éxécution de getx().
  3473.  
  3474. Autant l'utilisation des méthodes est bonne, elle ne nous a pas montrer sa
  3475. vraie puissance, qui ne vient seulement lors de l'utlisation de l'héritage.
  3476.  
  3477. Si j'hérite d'un objet qui a une méthode, je l'ai automatiquement dans le
  3478. nouvel objet:
  3479.  
  3480.     OBJECT truc OF machin PRIVATE      -> même que machin, + 1 champ de plus
  3481.       prut:INT
  3482.     ENDOBJECT
  3483.  
  3484.     DEF b:PTR TO truc
  3485.     NEW b
  3486.     ...
  3487.     b.getx()                            -> même méthode
  3488.  
  3489. La chose interressante vient maintenant, au lieu d'hériter d'une méthode, vous
  3490. pouvez aussi la redéfinir:
  3491.  
  3492.     PROC getx() OF chose IS self.x+1
  3493.  
  3494. (Il va sans dire que on peut aussi de nouvelles méthodes)
  3495. Ainsi aux places appropriées, on peut choisir de modifier légèrement le
  3496. comportement des méthodes qu'on a d'autres objets, tant que l'interface
  3497. (ie 'getx()') reste la même. Faire cela ne npus permet pas seulement de
  3498. réutiliser le code selectivement, mais aussi nous permet d'utiliser le
  3499. polymorphisme:
  3500.  
  3501.     PROC faitqquchose(o:PTR TO chose)
  3502.       ...
  3503.       o.getx()
  3504.       ...
  3505.     ENDPROC
  3506.  
  3507.     faitqquchose(a)
  3508.     faitqquchose(b)
  3509.  
  3510. On peut appeler ce PROC aussi bien avec a que b, comme les 2 sont compatibles
  3511. avec l'objet chose. Mais lequel des 2 implémentations de méthodes de getx()
  3512. est appelé pour o.getx() ? Réponse: les 2. Les appels de méthodes en E sont
  3513. ce que sont des appels de méthodes virtuelles dans d'autres langages: ils
  3514. agissent dynamiquement sur le type réel d'un objet (o) et appelle la méthode
  3515. appropriée.
  3516.  
  3517. Un exemple clair:
  3518.  
  3519.     -> exemple classique de polymorphisme OO
  3520.  
  3521.     OBJECT loc
  3522.       PRIVATE xpos:INT, ypos:INT
  3523.     ENDOBJECT
  3524.  
  3525.     OBJECT point OF loc
  3526.       PRIVATE couleur:INT
  3527.     ENDOBJECT
  3528.  
  3529.     OBJECT cercle OF point
  3530.       PRIVATE rayon:INT
  3531.     ENDOBJECT
  3532.  
  3533.     PROC show() OF loc IS WriteF('Je suis en Place!\n')
  3534.     PROC show() OF point IS WriteF('Je suis un Point!\n')
  3535.     PROC show() OF cercle IS WriteF('Je suis un Cercle!\n')
  3536.  
  3537.     PROC main()
  3538.       DEF x:PTR TO loc,
  3539.           l:PTR TO loc,
  3540.           p:PTR TO point,
  3541.           c:PTR TO cercle
  3542.       ForAll({x},[NEW l,NEW p,NEW c],`x.show())
  3543.     ENDPROC
  3544.  
  3545. Ci-dessus, x est un pointeur sur loc, beaucoup s'attendrait à x.show() pour
  3546. écrire 'Je suis en Place' 3 fois, mais au lieu de ça, il écrit la bonne chaine
  3547. pour chaque objet.
  3548.  
  3549. Si quelqu'un veut écrire cet exemple dans un langage non OO, il aura besoin
  3550. d'un SELECT pour chaque opération comme show(), de tester des valeurs
  3551. présentes dans l'objets pour voir ce que c'est. Si je veux rajouter une nouvelle
  3552. forme à cela, disons:
  3553.  
  3554.     OBJECT ellipse OF cercle
  3555.  
  3556. J'aurais besoin de changer tous les SELECTs dans toute mon application. Avec
  3557. le polymorphisme des objets, je n'écris qu'une méthode show(), et TOUT les codes
  3558. de mon application qui appelle x.show() agirons correctement quand x est
  3559. pointeur sur ellipse, même sans recompilation!
  3560.  
  3561. C'est difficile de montrer pourquoi c'est si puissant en quelques exemples, et
  3562. le meilleur moyen de le découvrir est de l'utiliser dans des applications
  3563. réelles. Et, comme je dit, lisez un livre dessus.
  3564.  
  3565. Comment marche le polymorphisme ?
  3566.  
  3567.     Dans les exemples ci-dessus, il est clair que le compilateur ne peut
  3568.     montrer quelle méthode il va appeler. C'est pourquoi le E utilise un
  3569.     'objet classe' ('class object'), et chaque objet créé reçoit un
  3570.     pointeur sur cet objet. Dans l'objet classe, toutes les informations
  3571.     sont sauvées, ce qui est commun pour tous les objets de ce type, comme les
  3572.     pointeur sur les méthodes.
  3573.     Lorsque le compilateur voit un appel du style x.show(), au lieu de regarder
  3574.     directement à show() qui appartient au type de 'x' (ie loc), il générera un
  3575.     code pour retrouver le pointeur sur la méthode show() à partir de l'objet
  3576.     classe 'loc'. Si tant que l'objet classe pour 'point' regarde la même chose
  3577.     que 'loc' (seulement peut-être un peu plus grand), ce code appellera
  3578.     automatiquement le show() de 'point', si 'x' est réellement un objet
  3579.     'point'. On appelle ça souvent 'runtime binding'.
  3580.  
  3581. Des objets qui ont des méthodes, sont par conséquent 4 octets plus grand que
  3582. vous pensez qu'ils sont, si ils contiennent un pointeur objet classe. Ce
  3583. pointeur est automatiquement installé par NEW, c'est la raison pour laquelle
  3584. NEW _pour le moment_ est la seule façon de crée un tel objet.
  3585.  
  3586. Si une méthode est déclarée avec le seul but qui permette à des classes
  3587. secondaires ('subclasses') de la redéfinir (ce type de classe est connu comme
  3588. une classe de base virtuelle ('virtual baseclass') dans certains langages),
  3589. vous pouvez utiliser EMPTY:
  3590.  
  3591.     PROC truc() OF bidule IS EMPTY
  3592.  
  3593. On peut effectivement ajouter des méthodes aux objets système:
  3594.  
  3595.     OBJECT mongadget OF gadget       -> à partir d'intuition!
  3596.       -> champ supplémentaire ici
  3597.     ENDOBJECT
  3598.  
  3599.     PROC creergadget() OF mongadget IS ...
  3600.  
  3601.  
  3602.  
  3603. +---------------------------------------------------------------+
  3604. |                      15. ASSEMBLEUR EN LIGNE                  |
  3605. +---------------------------------------------------------------+
  3606.  
  3607.  
  3608. 15A. utilisation des identificateurs
  3609. ------------------------------------
  3610.  
  3611. Comme vous l'aurez préssenti dans l'exemple du chapitre 5D, les instructions
  3612. assembleurs peuvent librement mélangé avec le code E. Le grand secret est
  3613. qu'un assembleur complet est construit dans le compilateur.
  3614. En plus des modes d'adressage assembleur normaux, vous pouvez utiliser les
  3615. identificateurs suivant :
  3616.  
  3617.     mylabel:
  3618.     LEA mylabel(PC),A1              /* labels */
  3619.  
  3620.     DEF a                           /* variables */
  3621.     MOVE.L (A0)+,a                  /* notez que <var> est un <offset>(A4) */
  3622.                                     /* (or A5) */
  3623.  
  3624.     MOVE.L dosbase,A6               /* identificateur d'appel */
  3625.                                     /* d'un bibliothèque */
  3626.     JSR    Output(A6)
  3627.  
  3628.     MOVEQ  #TRUE,D0                 /* constantes */
  3629.  
  3630.  
  3631. 15B. l'assembleur en ligne comparé à un macro assembleur
  3632. --------------------------------------------------------
  3633.  
  3634. L'assembleur en ligne diffère un peu d'un macro assembleur moyen, et ce à
  3635. cause du fait que c'est une extension du E, et qu'il obéit à la syntaxe du E.
  3636. Les grosses différences sont :
  3637.  
  3638. - les commentaires sont fait avec /* et */ et non par ';', ils ont une
  3639.   significations différentes.
  3640. - les mots-clé et registres sont en majuscules, tout est sensible (case
  3641.   sensitive).
  3642. - pas de macros ou autres (Il y a le langage E fait pour ça !)
  3643. - vous devez faire attention que les registres A4/A5 ne sont pas détruit par
  3644.   un code assembleur en ligne, car utilisé par le E.
  3645. - pas _encore_ de support pour le modèle LARGE/reloc-hunks en assembleur.
  3646.   Cela siginifie en pratique que vous devz utiliser un adressage relativ pour
  3647.   l'instant.
  3648.  
  3649.  
  3650. 15C. comment utiliser des données binaires (INCBIN/CHAR..)
  3651. ----------------------------------------------------------
  3652.  
  3653. INCBIN
  3654.  
  3655.     syntaxe:         INCBIN <nom_fichier>
  3656.  
  3657.     inclue un fichier binaire a ce point précis, doit être séparé du code.
  3658.     Exemple:
  3659.  
  3660.         montab: INCBIN 'df1:data/blabla.bin'
  3661.  
  3662.  
  3663. LONG, INT, CHAR
  3664.  
  3665.     syntaxe:         LONG <valeurs>,...
  3666.                      INT <valeurs>,...
  3667.                      CHAR <valeurs>,...
  3668.  
  3669.     vous permet de placer des données binaires dans votre programme comme
  3670.     DC.x en assembleur. Notez que la déclaration CHAR prend aussi les chaines,
  3671.     et sera toujours mis à un mot pair.
  3672.     Exemple :
  3673.  
  3674.     mes_données: LONG 1,2; CHAR 3,4,'Salut !',0,1
  3675.  
  3676.  
  3677. 15D. OPT ASM
  3678. ------------
  3679.  
  3680. On peut trouver quelques autres détails sur OPT ASM dans le chapitre 16A.
  3681. Cette option vous permet de mettre 'EC' en mode assembleur. Il n'y a aucune
  3682. bonne raison d'utiliser EC plutôt que quelques macro-assembleurs à part le
  3683. fait qu'il est significativement plus rapide que par exemple A68k, égale
  3684. DevPac et est derrière ASmOne (snif... 8-{). Vous passerez aussi beaucoup de
  3685. temps en essayant de réduire le nombre de disquettes des bons vieux sources
  3686. du Seka via EC, à cause des différences décrites dans la chapitre 15B. Si vous
  3687. voulez écrire un programme en assembleur avec EC, et voulez rendre le source
  3688. compatible avec d'autres assembleurs, simplement faites précéder chaque
  3689. élément spécifique du E d'un ';', EC les utilisera mais les autres assembleurs
  3690. les verrons comme commentaires.
  3691. Exemple :
  3692.  
  3693.     ; OPT ASM
  3694.  
  3695.     start:  MOVEQ   #1,D0           ; /* faite n'importe quoi */
  3696.             RTS                     ; /* et sort */
  3697.  
  3698. Ceci sera assemblé par n'importe quel assembleur, même EC
  3699.  
  3700.  
  3701. 15E. Assembleur en ligne et registres de variables
  3702. --------------------------------------------------
  3703.  
  3704. Les variables de registres sont de bons compagnions de l'assembleur en ligne,
  3705. car ils fonctionnent justement comme des registres, mais en même temps possède
  3706. des identificateurs clairs au lieu de Dx, et aussi sont automatiquement sauvés
  3707. et restauré par le code E.
  3708. Exemple:
  3709.  
  3710.     PROC bla()
  3711.       DEF compte:REG
  3712.       MOVEQ #10,compte
  3713.     boucle: WriteF('compte=\d\n',compte)
  3714.       DBRA compte,boucle
  3715.     ENDPROC
  3716.  
  3717. Toutes les instructions qui peuvent travailler avec Dx EA, marche avec les
  3718. variables de registre.
  3719. Exemples:
  3720.  
  3721.     MOVEQ #1,a
  3722.     MOVEM.L D0/D1/a/b/A0,-(A7)
  3723.     LSL.L a,b
  3724.  
  3725.     etc.
  3726.  
  3727. Comme vous le savez, EC utilise D3-D7 pour ses variables de registres. Si vous
  3728. voulez écrire un code qui mélange de l'assembleur avec le E, il est préférable
  3729. de garder des valeurs à long terme des les variables de registres, et les
  3730. temporaires dans d0-D2/A0-A3/A6.
  3731.  
  3732.  
  3733.  
  3734. +---------------------------------------------------------------+
  3735. |                    16. REVUE D'IMPLEMENTATION ET TECHNIQUE    |
  3736. +---------------------------------------------------------------+
  3737.  
  3738.  
  3739. 16A. le mot-clé OPT
  3740. -------------------
  3741.  
  3742. OPT, LARGE, STACK, ASM, NOWARN, DIR, OSVERSION, MODULE, EXPORT, RTD, REG
  3743.  
  3744.     syntaxe:         OPT <options>,...
  3745.     vous permet de changer les options par défaut du compilateur :
  3746.  
  3747.     LARGE           met le modèle de données et du code sur grand (LARGE).
  3748.                     Petit par défaut. Le compilateur génère un code 100%
  3749.                     relatif de style pc, avec un taile maximum de 32k. Avec
  3750.                     LARGE, il n'y a pas de limites, et reloc-hunks est généré.
  3751.                     Voir 0D, LARGE
  3752.     STACK=x         fixe la taille de la pile à x octets. A utiliser
  3753.                     uniquement si vous savez ce que vous faites. Normalement
  3754.                     le compilateur fait une bonne approximation de l'espace
  3755.                     nécessaire.
  3756.     ASM             met le compilateur en mode assembleur. A partir de là,
  3757.                     uniquement des instructions assembleur sont acceptés, et
  3758.                     aucun code d'initialisation n'est généré. Voir le chapitre
  3759.                     assembleur en ligne 16C.
  3760.     NOWARN          Ne fait pas afficher les avertissements. Le compilateur
  3761.                     vous préviendra si il *pense* que votre programme est
  3762.                     incorrect, mais a une bonne syntaxe. Voir 0D, NOWARN
  3763.     DIR=moduledir   fixe le répertoire dans lequel le compilateur cherchera
  3764.                     les modules. 'Emodules:' par défault
  3765.     OSVERSION=ver   =33 par défaut (v1.2). Fixe la version minimum du
  3766.                     kickstart (comme 37 pour v2.04)sur lequel votre programme
  3767.                     doit tourner. Comme ca, votre programme ne s'arrêtera lors
  3768.                     de l'ouverture de la dos.library si vous avez une ancienne
  3769.                     machine. En tout cas, vérifiez vous-même la version et
  3770.                     donner un message d'erreur approprié sera une aide à
  3771.                     l'utilisateur.
  3772.     MODULE          fait considérer le source comme module. (voir 10C)
  3773.     EXPORT          exporte automatiquement toutes les déclarations dans le
  3774.                     source principal.
  3775.     RTD             génère RTD au lieu de RTS dans le source principal.
  3776.                     020+ seulement. [optimisation expérimentale]
  3777.     020,881,040     génère un code pour utilisation avec ces puces. Pas
  3778.                     vraiment utilisable encore.
  3779.  
  3780.     Exemple:
  3781.  
  3782.     OPT STACK=20000,NOWARN,DIR='df1:modules',OSVERSION=39,REG=3
  3783.  
  3784.  
  3785. 16B. petit et grand modèle
  3786. --------------------------
  3787.  
  3788. L'Amiga E vous laisse le choix entre un petit (SMALL) et un grand (LARGE)
  3789. modèle. Notez que la plupart des programmes que vous écrirez (spécialement si
  3790. vous débutez en E) rentrera dans les 32 Ko une fois compilés : vous n'aurez
  3791. pas à vous soucier du modèle du code. Vous saurez qu'il faudra utiliser le
  3792. grand modèle dès que EC commencera à dire qu'il ne peut plus réduire le code
  3793. à 32k. Pour compiler un source avec un grand modèle :
  3794.  
  3795.     1> ec -l grand.e
  3796.  
  3797. ou mieux encore, mettez
  3798.  
  3799.     OPT LARGE
  3800.  
  3801. dans votre code.
  3802.  
  3803.  
  3804. 16C. organisation de la pile
  3805. ----------------------------
  3806.  
  3807. Pour garder les variables locales et globales, le système d'un éxécutable
  3808. généré par Amiga E alloue un bloc de mémoire, duquel il prendra un bout pour
  3809. les variables globales. Le reste sera utilisé dynamiquement par les appels
  3810. des fonctions.
  3811.  
  3812. Quand une fonction est appelé en E, un espace dans la pile est reservée
  3813. pour les données locales, qui sera libéré à la sortie de la fonction.
  3814. C'est pourquoi avoir un grand tableau comme données locales peut être
  3815. dangereux si utilisé récursivement : toutes les données de lappel précédent
  3816. de la même fonction reste dans la pile, et consomme une grande partie de la
  3817. pile encore libre. Toutefois si les procédures sont correctement appelées,
  3818. il n'y a aucune raison d'avoir un débordement.
  3819. Exemple:
  3820.  
  3821.     donnée globale       :     10k (par ex. un tableau)
  3822.     donnée locale PROC #1:      1k
  3823.     donnée locale PORC #1:      3k
  3824.  
  3825. Le système reserve toujours 10k d'espace supplémentaire pour les récursions
  3826. normales (par exemple avec un petit tableau local) et des espaces pour des
  3827. tampons (buffers) et le système, qui prendront en tout 24 k de pile en plus.
  3828.  
  3829.  
  3830. 16D. limites du code
  3831. --------------------
  3832.  
  3833. Notez ces signes : (+-)   = dépend du contexte
  3834.                    (n.l.) = pas de limite, mais semble raisonnable.
  3835.  
  3836. --------------------------------------------------------------------------
  3837. OBJECT/ITEM (objet/membre)                      SIZE/AMOUNT/MAX (taille)
  3838. --------------------------------------------------------------------------
  3839.  
  3840. type de donnée CHAR                             0 .. 255
  3841. type de donnée INT                              -32 k .. +32 k
  3842. type de donnée LONG/PTR                         -2 gig .. +2 giga
  3843.  
  3844. longueur d'identificateur                       100 octets (n.l.)
  3845. longueur d'un ligne de commandes                2000 tokens léxicaux(+-)
  3846. longueur d'un source                            2 giga (théoriquement)
  3847. listes de constantes                            quelques 100aines (+-)
  3848. chaines constantes                              1000 chars (n.l.)
  3849. nombre max. de boucle imbriqué (IF, FOR etc.)   500
  3850. nombre max. de commentaire imbriqué             infini
  3851.  
  3852. # de variables locales par procédure            8000
  3853. # de variables globales                         7500
  3854. # d'arguments pour vos propres fonctions        8000 (ensemble avec locales)
  3855. # d'arguments de fonction E (WriteF())          64
  3856.  
  3857. un objet (alloué en local/global ou dyn.)       8 k
  3858. un tableau, liste ou chaine (local or global)   32 k
  3859. une chaine (dynamique)                          32 k
  3860. une liste (dynamique)                           128 k
  3861. un tableau (dynamique)                          2 giga
  3862. des objets avec NEW                             64 k élem.
  3863. CHAR/INT/LONG/ avec NEW                         2 giga
  3864.  
  3865. données locales par procédure                   250 méga
  3866. données globales                                250 méga
  3867.  
  3868. taille du code d'une procédure                  32 k
  3869. taille du code d'un éxécutable                  32 k en petit (SMALL) modèle,
  3870.                                                 2 giga en grand (LARGE) modèle
  3871. limite courante (étendu dans la futur)          2-5 méga
  3872.  
  3873. taille des tampons du code généré
  3874.  et des identificateurs                         suivant le source
  3875. taille des tampons des labels/branches et
  3876.  intermédiaire                                  (re) alloué indépendamment
  3877.  
  3878.  
  3879. 16E. les messages d'erreurs, d'avertissements et de non référence
  3880. -----------------------------------------------------------------
  3881.  
  3882. Quelques fois, à la compilation de votre source avec EC, vous aurez un
  3883. message du style : UNREFFRENCED: <ident>, <ident>, ...
  3884. C'est le cas si vous déclarez des variables, fonctions ou labels dont vous
  3885. ne vous servez pas. C'est en service qui vous est rendu par le compilateur
  3886. pour vous aidez à trouver ces erreurs difficiles à trouver.
  3887.  
  3888. Il y a plusieurs avertissements que le compilateur envoie pour vous dire que
  3889. quelquechose devrait mal se passer, mais n'est pas vraiment une erreur.
  3890.  
  3891.  
  3892. - 'A4/A5 used in inline assembly'   'A4/A5 utilisé dans les lignes assembleur'
  3893.  
  3894.   Cet avertissment  apparait lorsque vous utilisez les registres A4 ou A5 dans
  3895.   votre code. La raison de cela est que ces registres sont utilisé de façon
  3896.   interne par le E pour adreser les variables globales et locales.
  3897.   Bien sûr il y a de bonne raison de les utiliser, comme pour faire un
  3898.   MOVEM.L A4/A5,-(A7) avant un grand morceau de code assembleur.
  3899.  
  3900.  
  3901. - 'keep an eye on your stacksize'       'jetez un oeil à la taile de votre pile'
  3902. - 'stack is definitely too small'       'la pile est vraiment trop petite'
  3903.  
  3904.   Ces deux apparaitrons si vcous utilisez OPT STACK=<size>. Le compilateur
  3905.   comparera votre taille à sa propre estimation (voir le chapitre 16C), et
  3906.   retournera la première des erreurs si il pense que c'est bien mais un peu
  3907.   juste, et la seconde si c'est bien trop petit.
  3908.  
  3909.  
  3910. - 'suspicious use of "=" in void expressions (s). (line %d)'
  3911.          'mauvaise utilisation de "=" dans une expression vide (s). (ligne %d)'
  3912.  
  3913.   Cet avertissment sera retourné si vous écrivez des expressions comme 'a=1'
  3914.   comme déclaration. Un raison de cela est le fait qu'un comparaison n'a pas
  3915.   de sens comme déclaration, mais la principale raison est que cela provient
  3916.   souvent d'une faute de frappe en voulant écrire 'a:=1'. Oublier ces ':'
  3917.   serait difficile à trouver, et aurait des conséquences désastreuses.
  3918.  
  3919.  
  3920. - 'module changed OPT settings'     'changement des OPTs par le module'
  3921.  
  3922.   Si vous utilisez un module qui a OPT OSVERSION=37, cette modification
  3923.   affecte aussi l'OPT du programme principal. Cette alerte sert à vous en
  3924.   rappeler. Mettez un OPT identique dans le programme principal pour
  3925.   l'enlever.
  3926.  
  3927.  
  3928. - 'variable used as function'       'variable utilisée comme fonction'
  3929.  
  3930.   Dans la v3, des variables arbitraires peuvent être utilisées comme fonction.
  3931.   Cette fonction est là pouyr vous prévenir de ne pas le faire
  3932.   accidentellement.
  3933.  
  3934.  
  3935. - 'code outside PROCs'
  3936.  
  3937.     Vous avez écrit du code E entre 2 PROC, ce qui est rarement utile.
  3938.  
  3939.  
  3940. Erreurs.
  3941.     Le compilateur affichera la ligne du code source qui a causé l'erreur ; et
  3942. un curseur en indiquera l'endroit précis. Le curseur indique le point où le
  3943. compilateur était quan il a _découvert_ l'erreur, il est donc certain que le
  3944. symbole qui a provoqué l'erreur est celui juste _avant_ le curseur.
  3945.  
  3946. - 'syntax error'    'Erreur de syntaxe'
  3947.  
  3948.     Erreur le plus souvent rencontrée. Cette erreur survient soit
  3949.     lorsqu'aucune autre erreur est appriopriée, soit l'agencment de votre
  3950.     code est anormal.
  3951.  
  3952.  
  3953. - 'unknown keyword/const'   'mot-clé ou constantes inconnus'
  3954.  
  3955.     Vous avez utilisé un identificateur en majuscule (comme 'IF' ou 'TRUE'),
  3956.     et le compilateur ne trouve aucune définition. Causes :
  3957.     - mot-clé mal écrit,
  3958.     - vous utilisez une constante, mais vous avez oublié de la définir dans
  3959.       la déclaration d'un CONST,
  3960.     - vous avez oublié to spécifier le module dans lequel la constante est
  3961.       définie.
  3962.  
  3963.  
  3964. - '":=" expected'   '":=" nécessaire'
  3965.  
  3966.     Vous avez écrit un FOR ou un assignement, et écrit quelque chose d'autre
  3967.     que ':='.
  3968.  
  3969.  
  3970. - 'unexpected characters in line'   'caractères non corrects dans la ligne'
  3971.  
  3972.     Vous utilisez des caratères en dehors d'une chaine, et qui n'ont aucun
  3973.     sens pour le E
  3974.     Exemple : @, !, &, \, ~
  3975.  
  3976.  
  3977. - 'label expected'  'label nécessaire'
  3978.  
  3979.     A certains endroits, par exemple aprés un PROC ou un JUMP, un label est
  3980.     nécessaire, et vous avez écrit autre chose.
  3981.  
  3982.  
  3983. - '"," expected'    '"," nécessaire'
  3984.  
  3985.     En spécifiant une list d'éléments (par exemple une liste de paramètres)
  3986.     vous avez écrit quelque chose d'autre à la place de la virgule.
  3987.  
  3988.  
  3989. - 'variable expected'   'variable nécessaire'
  3990.  
  3991.     Cette construction demande un variable.
  3992.     Exemple :
  3993.         FOR <var>:= ... etc.
  3994.  
  3995.  
  3996. - 'value does not fit in 32 bit'    'valeur ne rentre pas dans les 32 bits'
  3997.  
  3998.     En spécifiant une constante (voir les chapitres 2A-2E), vous avez écrit
  3999.     un nombre trop grand (par exemple : $FFFFFFFFF, "abcdef").
  4000.     Cette erreur apparait aussi lorsque vous définissez plus de 32 éléments
  4001.     dans la déclaration d'un SET.
  4002.  
  4003.  
  4004. - 'missing apostrophe/quote'    'apostrophe/cote manquante'
  4005.  
  4006.     Vous avez oublié une ' à la fin de la chaine.
  4007.  
  4008.  
  4009. - 'incoherent program structure'    'structure incohérente du programme'
  4010.  
  4011.     - vous avez commencé une nouvelle procédure (PROC) avant de terminer
  4012.       la précédente.
  4013.     - vous n'avez pas correctement inclue les boucles les unes dans les
  4014.       autres.
  4015.       Exemple :
  4016.         FOR
  4017.           IF
  4018.           ENDFOR  /* inversion du ENDFOR et du ENDIF */
  4019.         ENDIF
  4020.  
  4021.  
  4022. - 'illegal command-line option'     'mauvaise option dans la ligne de commande'
  4023.  
  4024.     En spécifiant 'EC -opt source' vous avez écrit les options avec quelque
  4025.     chose que EC ne connait pas.
  4026.  
  4027.  
  4028. - 'division and multiplication 16bit only'
  4029.                             'division et multiplication seulement sur 16 bits'
  4030.  
  4031.     Le compilateur a détecté que vous utilisez des valeurs sur 32 bits pour
  4032.     * ou /. Cela ne donnera pas la valeur désiré lorsque le programme sera
  4033.     lancé. Voir Mul() et Div().
  4034.  
  4035.  
  4036. - 'superfluous items in expression/statement'
  4037.                                 'trop de membres dans l'expression/déclaration'
  4038.  
  4039.     Après la compilation, le compilateur trouve touours des 'tokens' au lieu
  4040.     d'une fin de fichier (end of line). Vous avez probablement oublié une
  4041.     saut de ligne <lf> ou un ';' pour séparer 2 déclarations.
  4042.  
  4043.  
  4044. - 'procedure "main" not available'      'pas de procédure Main()'
  4045.  
  4046.     Votre programme n'a pas de proceédure Main() !
  4047.  
  4048.  
  4049. - 'double declaration of label'     'double déclaration d'un label'
  4050.  
  4051.     Vous avez déclaré 2 fois un label.
  4052.     Exemple :
  4053.         label:
  4054.         PROC label()
  4055.  
  4056.  
  4057. - 'unsafe use of "*" or "/"'    'utilisation peu prudente de "*" ou "/"'
  4058.  
  4059.     Ceci encore concerne les 16 bits au lieu des opérateur 32 bits * ey /.
  4060.     Voir 'division and multiplication 16bit only'.
  4061.  
  4062.  
  4063. - "reading sourcefile didn't succeed"
  4064.                                 'la lecture du fichier source n'a pas réussi'
  4065.  
  4066.     Vérifiez votre source, en particulier si en donnant 'ec monsource',
  4067.     assurez vous que le nom du fichier se termine par '.e' (ce qui n'est pas
  4068.     le cas dans la ligne de commande)
  4069.  
  4070.  
  4071. - "writing executable didn't succeed"
  4072.                                     'l'écriture de l'éxécutable n'a pas réussi'
  4073.  
  4074.     En écrivant le code généré, comme éxécutable, le DOS retourne une erreur.
  4075.     Par exemple, l'éxécutable déja existant ne peut être effacé et réécrit.
  4076.  
  4077.  
  4078. - 'no args'     'pas d'arguments'
  4079.   "USAGE: ec [-opts] <sourcecodefilename> (`.e' is added)"
  4080.                   "USAGE: ec [-opts] <nom_du_fichier_soure> (`.e' est rajouté)"
  4081.  
  4082.     Vous aurez ceci en tapant uniquement 'ec', sans arguments.
  4083.  
  4084.  
  4085. - 'unknown/illegal addressing mode'     'mode d'adressage inconnu/illégal'
  4086.  
  4087.     Cette erreur est retourné uniquement par les lignes assembleur. Les causes
  4088.     possibles sont :
  4089.     - vous avez utilisé un mode d'adressage qui n'éxiste pas sur le 68000,
  4090.     - le mode d'adressage éxiste, mais pas pour cette instruction.
  4091.       Toutes les instructions assembleur ne supporte pas tutes les
  4092.       combinaisons d'adresses effective comme source et destination.
  4093.  
  4094.  
  4095. - 'unmatched parentheses'   'mauvais nombre de parenthèses'
  4096.  
  4097.     Votre déclaration comporte plus de '(' que de ')' ou l'inverse.
  4098.  
  4099.  
  4100. - 'double declaration'      'double déclaration'
  4101.  
  4102.     Un identificateur est utilisé dans 2 ou plus déclarations.
  4103.  
  4104.  
  4105. - 'unknown identifier'      'identificateur inconnu'
  4106.  
  4107.     Un identificateur n'est utilisé dans aucune déclaration; il est inconnu.
  4108.     Vous avez certainement oublié de le mettre dans la déclaration DEF.
  4109.  
  4110.  
  4111. - 'incorrect #of args or use of ()'    'nombre incorrect d'arguments ou de ()'
  4112.  
  4113.     - vous avez oublié de mettre une '(' ou une ')' au bon endroit,
  4114.     - vous donner un nombre incorrect d'argument à un fonction.
  4115.  
  4116.  
  4117. - 'unknown e/library function'      'fonction inconnue du E/bibliothèque'
  4118.  
  4119.     Vous avez écrit un identificateur avec le premier caractère en majuscule,
  4120.     et le second en minuscule, mais le compilateur ne trouve aucune
  4121.     définition. Causes possibles :
  4122.     - le nom de la fonction est mal écrit,
  4123.     - vous avez oublié d'inclure le module qui défini l'appel de la
  4124.       bibliothèque.
  4125.  
  4126.  
  4127. - 'illegal function call'       'appel de fonction illégal'
  4128.  
  4129.     N'arrive que rarement. Vous l'aurez si vous essayez de construire
  4130.     des appels de fonction complexe, comme :
  4131.         WriteF(WriteF('hi!'))
  4132.  
  4133.  
  4134. - 'unknown format code following "\"'   'format du code suivant "\" inconnu'
  4135.  
  4136.     Vous spécifiez un code de format dans une chaine, qui est illégal.
  4137.     Voir le chapitre 2F pour une liste des codes de format.
  4138.  
  4139.  
  4140. - '/* not properly nested comment structure */'
  4141.                                         '/* commentaires mal imbriqués */'
  4142.  
  4143.     Le nombre de '/*' n'est pas égal au nombre de '*/', ou placé dans un
  4144.     ordre bizarre.
  4145.  
  4146.  
  4147. - 'could not load binary'       'ne peut pas ouvrir la bibliothèque'
  4148.  
  4149.     le fichier spécifié dans le ligne INCBIN <fichier> ne peut pas être lu.
  4150.  
  4151.  
  4152. - '"}" expected'        '"}" nécessaire'
  4153.  
  4154.     Vous avez commencé une expression comme '{<var>', et vous avez oublié
  4155.     le "}".
  4156.  
  4157.  
  4158. - 'immediate value expected'        'valeur immédiate nécessaire'
  4159.  
  4160.     Certaines constructions demandent une valeur immédiate à la place d'une
  4161.     expression.
  4162.     Exemple :
  4163.         DEF s[x*y]:STRING   /* mauvais :uniquement quelque chose comme */
  4164.                             /* s[100]:STRING est bon */
  4165.  
  4166.  
  4167. - 'incorrect size of value'     'taille de la valeur incorrecte'
  4168.  
  4169.     Vous spécifiez une valeur trop grande (ou trop petite).
  4170.     Exemples:
  4171.         DEF s[-1]:STRING, t[1000000]:STRING   /* doit être entre 0..32000  */
  4172.         MOVEQ #1000,D2                        /* doit être entre -128..127 */
  4173.  
  4174.  
  4175. - 'no e code allowed in assembly modus'
  4176.                                     'pas de code E accepté en mode assembleur'
  4177.  
  4178.     Vous voulez compiler en mode assembleur, en écrivant 'OPT ASM', et par
  4179.     accident, vous avez mis du code E.
  4180.  
  4181.  
  4182. - 'illegal/inappropriate type'      'type inapproprié/illégal'
  4183.  
  4184.     A certain endroit ou un <type> est demandé, vous avez écrit quelque chose
  4185.     d'inaproprié.
  4186.     Exemple :
  4187.         DEF a:PTR TO ARRAY       /* aucun type de ce type :) */
  4188.         [1,2,3]:STRING
  4189.  
  4190.  
  4191. - '"]" expected'        '"]" nécessaire'
  4192.  
  4193.     Vous avez commencé avec un "[", mais vous avez oublié de terminer
  4194.     avec un "]".
  4195.  
  4196.  
  4197. - 'statement out of local/global scope'
  4198.                    'déclaration en dehors des déclarations locales ou globales'
  4199.  
  4200.     Un point de déclaration est la première déclaration PROC. Avant ça,
  4201.     uniquement des définitions globales (DEF, CONST, MODULE, etc) sont
  4202.     permises, et aucun code. Dans la secondes parties, seulement les
  4203.     définitions de code et de fonctions sont légales, aucune définition
  4204.     globale n'est possible.
  4205.  
  4206.  
  4207. - 'could not read module correctly'     'ne peut lire le module correctement'
  4208.  
  4209.     Une erreur du DOS est survenue en voulant lire un module à partir de la
  4210.     déclaration MODULE. Causes :
  4211.     - 'Emodules:' est mal assigné,
  4212.     - le nom du module est mal écrit, ou n'éxiste pas,
  4213.     - vous avez écrit MODULE 'bla.m' au lieu de 'bla' (sans suffixe).
  4214.  
  4215.  
  4216. - 'workspace full!'     'espace de travial plein !'
  4217.  
  4218.     N'arrive que rarement. Si cela survient, you devez mettre l'option '-m'
  4219.     pour forcer manuellement EC à faire une estimation plus large sur la
  4220.     quantité de mémoire nécessaire.
  4221.     Essayez de compiler avec -m2, puis -m3 jusqu'à ce que l'erreur
  4222.     disparaisse. Vous aurez certainement écrit une gigantesque application
  4223.     avec une grande quantité de données pour arriver à cette erreur.
  4224.  
  4225.  
  4226. - 'not enough memory while (re-)allocating'
  4227.                               'pas assez de mémoire pendant la (ré)allocation'
  4228.  
  4229.     Tout simplement. Solutions possibles :
  4230.     1. vous avez plusieurs programmes marchant en multitache. Quittez en
  4231.        quelques uns et reéssayez.
  4232.     2. il vous reste peu de mémoire, ou votre mémoire est fragmentée.
  4233.     3. aucun des 2 possibilités. Achetez de la mémoire (Hum..)
  4234.  
  4235.  
  4236. - 'incorrect object definition'     'définition d'objet incorrect'
  4237.  
  4238.     Vous avez écrit quelque chose en OBJECT et ENDOBJECT qui n'est pas
  4239.     correct. Voir le chapitre 8F pour savoir comment bien écrire.
  4240.  
  4241.  
  4242. - 'illegal use of/reference to object'
  4243.                                 'mauvaise utilisation ou référence à un objet'
  4244.  
  4245.     Si vous utilisez une expressions comme ptr.membre, membre doit être un
  4246.     membre définit dans l'object ptr.
  4247.  
  4248.  
  4249. - 'incomplete if-then-else expression'     'expression if-then-else incomplète'
  4250.  
  4251.     Si vous utilisez IF comme opérateur (chapitre 4E), alors un ELSE doit
  4252.     être présent : une expression avec un IF à l'interieur a toujours besoin
  4253.     de retourner une valeur, alors qu'une déclaration avec un IF peut ne rien
  4254.     faire si aucun ELSE n'est présent.
  4255.  
  4256.  
  4257. - 'unknown object identifier'       'identificateur d'objet inconnu'
  4258.  
  4259.     Vous utilisez un identificateur qui est reconnu par le compilateur comme
  4260.     une partie d'un objet, et vous avez oublié de le déclarer. Causes :
  4261.     - nom mal écrit,
  4262.     - module manquant,
  4263.     - l'identificateur dans le module est écrit différemment de ce que vous
  4264.       pensiez (des RKRM par exemple) Vérifiez avec ShowModule.
  4265.       Notez que le système d'objet Amiga hérite des identificateurs de
  4266.       l'assembleur, pas du C. Les identificateurs obéissent à la syntaxe
  4267.       du E.
  4268.  
  4269.  
  4270. - 'double declaration of object identifier'
  4271.                                 'double déclaration d'idenficateur d'objet'
  4272.  
  4273.     Un identificateur est utilisé dans le définition de 2 objets.
  4274.  
  4275.  
  4276. - 'reference(s) out of 32k range: switch to LARGE model'
  4277.                 'référence(s) en dehors des 32ko : utilisez le grand modèle'
  4278.  
  4279.     Votre programme est plus grand que 32ko. Mettez simplement 'OPT LARGE'
  4280.     dans votre code source. Voir le chapitre 16B.
  4281.  
  4282.  
  4283. - 'reference(s) out of 256 byte range' 'référence(s) en dehors des 256 octets'
  4284.  
  4285.     Vous avez probablement écrit BRA.S ou Bcc.S sur un trop grand espace.
  4286.  
  4287.  
  4288. - 'too sizy expression'     'expression trop grande'
  4289.  
  4290.     Vous utilisez une liste, qui est peut-être récursivment, qui est trop
  4291.     grande.
  4292.  
  4293.  
  4294. - 'incomplete exception handler definition'
  4295.                         'définition incomplète du gestionnaire d'exception'
  4296.  
  4297.     Vous avez certainement utilisé EXCEPT sans HANDLE, ou quelque chose dans
  4298.     ce genre. Voir le chapitre 13A sur les gestions d'exception.
  4299.  
  4300. - 'not allowed in a module'         'non permis dans un module'
  4301.  
  4302.     Vous faites quelques choses que vous ne pouvez pas faire dans un module,
  4303.     comme des variables globales avec initialisations.
  4304.  
  4305. - 'allowed in modules only'         'permis uniquement dansles modules'
  4306.  
  4307.     Vous avez certainmenet utiliser EXPORT dans le programme principal.
  4308.  
  4309. - 'this doesn't make sense'         'ça n'a aucun sens'
  4310.  
  4311.     Erreur générale.
  4312.  
  4313. - 'you need a newer version of EC for this :-)'
  4314.                      'vous avez besoin d'une version récente de EC pour ça :-)'
  4315.  
  4316.     Vous utilisez certainement un module qui a été compiler avec un version
  4317.     plus récente de EC, que la votre.
  4318.  
  4319. - 'no matching "["'             'pas de "["'
  4320.  
  4321.   Dans une déclaration, un "]" a été trouvé, mais pas son "]" correspondant.
  4322.  
  4323. - 'this instruction needs a better CPU/FPU (see OPT)'
  4324.             'cette instruction a besoin d'un CPU/FPU plus puissant (voir OPT)'
  4325.  
  4326.     Vous utilisez une construction (probablement une instruction asm) qui
  4327.     nécessite un OPT 020 ou ce genre.
  4328.  
  4329. - 'object doesn't understand this method'
  4330.                                        'l'objet ne comprend pas cette méthode'
  4331.  
  4332.     Vous invoquez une méthode sur un objet qui n'est pas défini pour ce type.
  4333.  
  4334. - 'method doesn't have same #of args as method of baseclass'
  4335.           'la méthode n'a pas le même nombre d'argument que la méthode de base'
  4336.  
  4337.     Si vous redefinissez une méthode, vous devez vous assurer que la nouvelle
  4338.     a le même nombre d'argument que l'original.
  4339.  
  4340. - 'toomuch register variables in this function'
  4341.                             'trop de variables de registre dans cette fonction'
  4342.  
  4343.     Si vous utilisez :REG pour assigner des variables de registre vous mêmes,
  4344.     vous ne pouyvez actuellement pas en utiliser plus de 5.
  4345.  
  4346. - 'Linker can't find all symbols'
  4347.                                 'le linker ne peut trouver tous les symboles'
  4348.  
  4349.     Si vous utilisez un module A qui utilise un module B, B doit être linké.
  4350.     A se trouve dans certain PROCs de B, et si B est recompilé sans ces PROCs,
  4351.     le linker aura des problêmes à rassembler le tout dans l'éxécutable.
  4352.  
  4353. - 'could not open "mathieeesingbas.library"'
  4354.                                  'ne peut ouvrir la 'mathieeesingbas.library"'
  4355.     Si vous utilisez un code flottant, le compilateur lui même aura besoin
  4356.     de fonctions flottantes pour être capable de générer le code.
  4357.  
  4358. - 'illegal destructor definition'       'définition illégale de destruction'
  4359.  
  4360.     Vous avez défini une méthode end() avec des arguments ou une valeur de
  4361.     retour.
  4362.  
  4363. - 'implicit initialisation of private members'
  4364.                                 'initialisation implicite de membres privés'
  4365.  
  4366.   Vous avez écrit une expression [...] ou NEW [...] qui des parties privées.
  4367.  
  4368. - 'double method declaration'               'déclaration de méthode double'
  4369.  
  4370.     Vous avez défini une méthode pour cet objet 2 fois.
  4371.  
  4372.  
  4373. 16F. organisation et allocation des tampons (buffer) du compilateur
  4374. -------------------------------------------------------------------
  4375.  
  4376. Quand vous recevez une erreur 'workspace full' (espace de travail plein)
  4377. (peu probable), ou si vous voulez savoir ce qui se passe quand votre
  4378. programme est compilé, il est utile de savoir comment EC organise ses
  4379. tampons.
  4380.  
  4381. Un compilateur, et c'est le cas d'EC, a besoin de tampons (buffers) pour le
  4382. suivi de beaucoup de choses, comme les identificateurs, etc., et pour y
  4383. mettre le code généré. EC ne sait pas de quelle taille doivent être les
  4384. tampons. Pour certains, ceux par exemple pour garder les constantes, il n'y
  4385. a pas de problêmes : si le tampons est plein lors de la compilation, EC alloue
  4386. un nouveau tampon et continue. D'autres tampons, comme celui réservé au code
  4387. généré, doit être continue en mémoire et ne peut être déplacé pendant la
  4388. compilation : EC doit donc faire une bonne estimation de la taille des tampons
  4389. pour être capable de compiler des sources de toutes tailles.
  4390. Pour faire cela, EC calcule la mémoire nécessaire suivant le cas du source
  4391. donné. Dans 99% des cas, EC aura alloué suffisament de mémoire pour compiler
  4392. quasiment tous les sources. Dans les autres cas, vous aurez un erreur à la
  4393. compilation et vous aurez à spécifier plus de mémoire grace à l'option '-m'.
  4394.  
  4395. Essayez les différents sources (de taille et de type différent) en les
  4396. combinant avec l'option '-b', pour voir comment ca marche en réalité.
  4397.  
  4398.  
  4399. 16G. allocation de registres
  4400. ----------------------------
  4401.  
  4402. E v3 supporte une allocation de registre, qui est une techinque pour garder
  4403. des variables dans des registres au lieu de la pile. Pour un code normal
  4404. qui utilise des routines OS, vous ne moterez pas trop la différence, mais pour
  4405. des petites boucles, cette optimisation peut faireun grande différence. Il y
  4406. a 2 moyens d'utiliser l'allocation:
  4407.  
  4408. - avec l'option REG.
  4409.   Si vous écrivez par exemple EC REG=3 truc.e, (max=5, pour le moment) EC
  4410.   calculera pour chaque PROC les variables les plus utilisées dans les
  4411.   registres. L'allocation des registres est une technique qui essaye d'être
  4412.   intelligente: elle calculera pour chaque variable un poids, par exemple une
  4413.   variable utilisée dans une boucle FOR aura un poids plus fort qu'une
  4414.   variable en dehors, et une dans un IF aura un poids plus faible. Ces poids
  4415.   sont combinés, donc un WHILE dans un FOR donnera un poids plutôt élevé.
  4416.  
  4417. - DIY: vous pouvez mettre le mot-clef REG devant n'importe quel type dans une
  4418.   déclaration, par exemple:
  4419.  
  4420.         DEF x:REG, s[4]:REG LIST
  4421.  
  4422.   vous pouvez faire cela si vous n'avez pas confiance à l'allocataire de
  4423.   registres, ou si vous voulez affiner juste un PROC. Vous pouvez même utiliser
  4424.   les deux ensembles: si dans un PROC vous avez une variable avec :REG,
  4425.   compiler avec REG=5 permettra à EC de faire les 4 restant de lui-même.
  4426.  
  4427. Le défaut est REG=0, donc EC marche plutôt comme les anciennes versions.
  4428.  
  4429. Les variables qui PEUVENT être allouées sont uniquement des variables locales
  4430. qui ne sont pas des paramêtres. Aussi, si vous prenez l'adresse d'une variable
  4431. avec {} elle ne peut être mise dansun registre (devinez pourquoi...). Les
  4432. registres ne peuvent pas être alloués dans des PROCs qui ont une gestion
  4433. d'exception, pour le moment.
  4434.  
  4435. Il y a quelques petites choses à noter lors de l'utilisation de registres:
  4436.     - cette partie de EC est en ce moment 3.0a a été testé pour être fiable,
  4437.       mais vérifiez toujours que ce comportement est le même qu'un code
  4438.       non alloué. Ca _doit_ marcher, mais il est trop tôt pour le garantir :-)
  4439.       En résumé: soyez prudent pour le moment quand vous appliquez ces
  4440.       techniques ;
  4441.     - EC utilise les registres D7..D3 pour les variables, ainsi si vous
  4442.       utilisez de l'assembleur, vous devez vérifiez que les PROCS qui utilise
  4443.       l'allocation de registre ou :REG ne se plante pas (voir 15E).
  4444.       Le code généré pour un PROC sauve automatiquement les registres qu'il
  4445.       utilise pour protéger le code qui l'appelle ;
  4446.     - conseil : compiler avec REG=5 n'est pas le plus rapide, tant que la
  4447.       sauvegarde de variables sur des appels de fonction/bibliothèque aussi
  4448.       s'attire un 'overhead'. REG=3 peut être mieux pour certains cas. Aussi si
  4449.       _tous_ les codes en question se rapportea des appels de bibliothèques au
  4450.       lieu de calcul pur, ne vous attendez pas à un gain dans les registres.
  4451.  
  4452. -> l'allocation de registres rendrait ce programme 2 fois plus rapide.
  4453.  
  4454.     PROC main()
  4455.       DEF a,b=10,c=20,d
  4456.       FOR a:=1 TO 1000000 DO d:=b+c
  4457.     ENDPROC
  4458.  
  4459. -> en gros 5% plus rapide quand on utilise l'allocation de registres
  4460.  
  4461.     PROC main()
  4462.       DEF a,s[100]:STRING,t
  4463.       t:='putting "a" in a reg won''t give that much of a speedup, I think.'
  4464.       FOR a:=1 TO 100000 DO StrCopy(s,t)
  4465.     ENDPROC
  4466.  
  4467.  
  4468.  
  4469. +---------------------------------------------------------------+
  4470. |                 17. Les Utilitaires Essentiels du E           |
  4471. +---------------------------------------------------------------+
  4472.  
  4473.  
  4474. 17A. bin/showmodule
  4475. -------------------
  4476.  
  4477. Comme vous l'aurez remarqué, l'équivalent des includes du E, les modules,
  4478. sont des fichiers binaires, comme ceux du compilateur Modula2, par exemple.
  4479. Pour afficher leur contenu de ces fichiers, en bon texte ASCII, vous devez
  4480. utiliser 'showmodule' :
  4481.  
  4482.     showmodule <modulespec>
  4483.  
  4484.     Exemples:
  4485.  
  4486.     1> showmodule emodules:intuition/intuition
  4487.     1> showmodule >gadtools.txt emodules:gadtools
  4488.  
  4489. Notez que showmodule écrit par défaut sur la console, et peut être arrêté
  4490. par CTRL-C.
  4491.  
  4492.  
  4493.  
  4494. 17B. sources/utilitaires/showhunk.e, bin/showhunk
  4495. -----------------------------------------------
  4496.  
  4497. Affiche tous les types de fichiers éxécutables, ainsi que les fichiers
  4498. objets '.o' généré par d'autre compilateurs/assembleurs.
  4499. ShowHunk vous affichera dans une (très simple) forme, la structure des
  4500. éxécutables générés par EC, mais aussi supporte des fichiers overlay
  4501. complexes. Dumpe aussi les labels (comme les XREF et les XDEF).
  4502.  
  4503. Le plus important, ShowHunk possède un désassembleur pour les code-hunks.
  4504. Mettez l'option 'DISASM/S'
  4505.  
  4506.     Exemple :
  4507.  
  4508.     showhunk <exefile>
  4509.  
  4510.     Comme:   1> showhunk helloworld
  4511.              1> showhunk disasm dpaint
  4512.  
  4513.  
  4514. 17C. bin/iconvert, bin/pragma2module
  4515. ------------------------------------
  4516.  
  4517. Ces 2 utilitaires sont pour les programmeurs E avancés seulement. Si vous
  4518. ne vous sentez pas à la hauteur, sautez cette partie.
  4519.  
  4520. [NOTE: comme l'utilitaire showmodule, les sources de ces utilitaires ont
  4521. été enlevé de la distribution, parce que des personnes ont mal utilisé leur
  4522. connaissance du format des modules .m. C'est PRIVÉE. Contactez moi d'abord
  4523. si vous voulez faire quelquechose avec.]
  4524.  
  4525. Iconvert convertie les définitions de constantes et de structures en assembleur,
  4526. des fichiers '.i' en modules E. Pragma2module fait la même chose avec les
  4527. fichiers de définition de bibliothèques pragma du compilateur SAS/C.
  4528. Bien sûr, tous les includes de Commodore sont déja converties de cette façon,
  4529. mais, disons que vous trouvez une chouette bibliothèque dans le domaine
  4530. publique, vous aurez besoin de ces utilitaires.
  4531.  
  4532. Comment faire :
  4533.  
  4534.     La plupart des bibliothèques sont fournies avec les définitions, mieux
  4535.     encore, avec les appels des fonctions, tout comme les constantes et les
  4536.     structures (OBJECT en E) que la bibliothèque utilise. Imaginons qu'elle
  4537.     s'appelle 'tools.library', vous devriez avoir :
  4538.  
  4539.         pragmas/tools_pragmas.h
  4540.         includes/tools.h
  4541.         includes/tools.i
  4542.  
  4543.     puis faites:
  4544.  
  4545.         1> pragma2module tools_pragmas.h
  4546.  
  4547.     Maintenant, vous pouvez utiliser dans votre programme la bibliothèque
  4548.     'tool.library'
  4549.  
  4550.     Exemple :
  4551.  
  4552.         MODULE 'tools'
  4553.  
  4554.         PROC main()
  4555.           IF (toolsbase:=Openlibrary('tools.library',37))=NIL THEN error()
  4556.  
  4557.         toolsfunc()
  4558.  
  4559.         ...etc.
  4560.  
  4561.     Convertissez 'tools.i' avec Iconvert en un autre 'tools.m' que vous
  4562.     mettrez dans emodules:libraries/, par exemple. Iconvert a besoin de
  4563.     l'assembleur A68k (domaine publique) pour faire le dur travail de
  4564.     compréhension de l'assembleur.
  4565.  
  4566.         1> iconvert tools.i
  4567.  
  4568.     Regardez avec Showmodule ce qu'est devenu le fichier '.i'.
  4569.     Utilisez le dans votre programme avec :
  4570.  
  4571.         MODULE 'libraries/tools'
  4572.  
  4573.         DEF x:toolsobj, y=TOOLS_CONST
  4574.  
  4575. Convertir avec Iconvert demande quelques notion d'assembleur, car
  4576. Iconvert fait confiance au format du fichier '.i', comme les includes
  4577. assembleur de Commodore. Environ 10% des fichier '.i' ont besoin d'être
  4578. retouché à la main pour être 'convertissable'.
  4579. Les définitions qu'Iconvert juge être correctes sont les suivants :
  4580.  
  4581.     <label> EQU <any_expression>
  4582.  
  4583.     STRUCTURE <sname>,0      ; if <>0, then   <struct>_SIZEOF
  4584.     ULONG <sname>_<label>
  4585.     BPTR <sname>_<label>
  4586.        ; etc.
  4587.     LABEL <sname>_SIZEOF     ; or "_SIZE"
  4588.  
  4589. Pour avoir une idée, quel expression assembleur Iconvert peut reconnaitre,
  4590. jetez un coup d'oeil dans les includes assembleur de Commodore et comparez les
  4591. aux modules équivalents(par exemple Intuition.i).
  4592.  
  4593.  
  4594. 17D. bin/ShowCache, bin/FlushCache
  4595. ----------------------------------
  4596.  
  4597. Le module cache du E est un espqce mémoire qu'il est possible de garder des
  4598. modules .m entre 2 compilations. La première fois que vous utilisez un certain
  4599. module, EC le chargera à partir du disque et le mettra dans le cache. Les fois
  4600. suivantes, EC le retrouvera dans le cache et ne le rechargera pas. Si EC
  4601. compile un module dont une ancienne version est dans le cache, celui-ci sera
  4602. remplacé par la nouvelle version. Vous pouvez imaginer l'incroyable
  4603. accellération des opérations, même pour les gens qui ont un disque dur et qui
  4604. utilise beaucoup de modules et qui recompile souvent.
  4605.  
  4606. Pour voir ce qui est à un moment donné dans le cache (et combien de mémoire
  4607. il dépense :-), tapez :
  4608.  
  4609.     1> ShowCache
  4610.  
  4611. Un autre utilitaire, FlushCache, vous permet d'enlever des modules du cache.
  4612. Des raisons à cela :
  4613.     - vous ne pouvez pas vous permettre d'utiliser tant de mémoire,
  4614.     - vous avez créé un nouveau .m avec un programme autre que EC, vous devez
  4615.       donc l'enlever 'à la main'.
  4616. L'argument de FlushCache est la chaine de caractères qui apparait dans le nom
  4617. du module. Aucun argument signifie tout enlever.
  4618.  
  4619. Exemple :
  4620.  
  4621.     1> FlushCache                       ; vide tout le cache
  4622.     1> FlushCache intuition/            ; vide tout les modules en relation
  4623.                                         ; avec intuition
  4624.  
  4625. Vous pouvez utiliser EC avec l'option 'IGNORECACHE/S' pour compiler sans le
  4626. cache. Que le cache soit plein ou vide, EC chargera dans tous les cas à partir
  4627. du disque, et ne mettra rien de nouveau dansle cache éxistant.
  4628.  
  4629. Si 2 ECs essaie d'accéder au cache simultanément en multitache, le deuxième EC
  4630. agira comme si l'option 'IGNORECACHE/S' était mis.
  4631.  
  4632.  
  4633. 17E. rexx/ecompile.rexx
  4634. -----------------------
  4635. [Qui se garde les autres scripts Rexx ?]
  4636.  
  4637. C'est un script rexx pour CygnusEd (tm), et vous permet de compiler des
  4638. programmes E à partir de l'éditeur. Assignez seulement ce script à une
  4639. touche de fonction de l'éditeur avec 'Install Dos/Arexx command ...'
  4640. (Regardez dans le manuel de Ced, si vous n'êtes pas sûr).
  4641. Maintenant écrivez votre programme, et pressez Fx si vous voulez compilez.
  4642. Votre source sera sauvé si nécessaire, le compilateur sera chargé dans une
  4643. fenêtre à part, et le programme est lancé sur cette même console. Quand votre
  4644. programme est fait, pressez <Return> pour revenir dans l'éditeur (l'écran Ced
  4645. est automatiquement mis en avant par le script). Si une érreur apparait
  4646. pendant la compilation, le script laissera Ced sauter à la ligne de l'érreur,
  4647. après que vous aillez pressez <Return>.
  4648.  
  4649. Note : dans le script, les chemins d'accès au compilateur peuvent être trouvé.
  4650.        Vous aurez certainement à les changer. Le script copie EC en Ram:
  4651.        pour les systèmes avec un SYS: lent. Vous pouvez le désactiver si vous
  4652.        avez un disque dur.
  4653.  
  4654.  
  4655. 17F. bin/o2m
  4656. ------------
  4657.  
  4658. Si vous avez des sources assembleur de grande taille que vous voulez utiliser,
  4659. il serait préférable de les convertir 'à la main' en assembleur en ligne du E.
  4660. o2m vous permet vous permet d'avoir votre macro-assembleur les assemblant out
  4661. en un fichier .o, et o2, puis convertis ce fichier .o en un fichier .m
  4662. utilisable en E.
  4663.  
  4664. Exemple : Si vous avez un fixhier bla.o:
  4665.  
  4666.     1> o2m bla
  4667.  
  4668. donnera bla.m. Attention, le fichier .o doit obéir à certaines rêgles. Il doit
  4669. consister en juste un seul code-hunk avec des définitions externes (XDEFs)
  4670. pour chaque symbole que vous voulez définier à partir du E, et pas de XREFs.
  4671. Votre source doit ressembler à ça :
  4672.  
  4673.         XDEF add__ii
  4674.  
  4675.     add__ii:
  4676.             move.l  4(a7),d0
  4677.             add.l   8(a7),d0
  4678.             rts
  4679.  
  4680. Cet exemple montre un bout d'un code assembleur qui prend 2 arguments (d'ou les
  4681. 2 "i" pour entier). Les arguments peuvent être trouvé dans la pile, où 4(a7)
  4682. est le dernoier argument, 8(a7) le précédent etc.
  4683.  
  4684. Showhunk vous affichera:
  4685.  
  4686.         hunk_unit:
  4687. HUNK -1 hunk_name:
  4688.         hunk_code: 12 bytes
  4689.         hunk_ext
  4690.           add__ii = $0
  4691.  
  4692. Ce type de fichier .o est facilement transformable en .m par o2m:
  4693.  
  4694.     /* Ce module contient 12 octets de code! */
  4695.  
  4696.     PROC add(a,b)
  4697.  
  4698.  
  4699. Il y a 2 choses à noter:
  4700.     - si votre code utilise D3-D7/A4/A5, vous devriez le sauver ;
  4701.     - si un label n'a pas le "__" avec un "i" pour chaque fonction, celle-ci
  4702.       devient une fonction sans paramêtre. Ne vous inquiètez pas si le label
  4703.       définit des données, vous n'avez qu'a simplement prendre l'adresse de ce
  4704.       'proc' avec {}, et l'utiliser comme pointeur sur vos données.
  4705.  
  4706. Théoriquement, o2m peut être utiliser pour linker du code C aux programmes E,
  4707. mais en pratique c'est souvent impossible. Si votre compilateur C vous permet
  4708. de modifier ['tune'] le fichier .o un peu, ça doit marcher.
  4709.  
  4710. Quelques problêmes sont:
  4711.     - les définitions de fonctions C, par exemple _printf() ;
  4712.     - les définitions de variables globales créées par le code startup du C ;
  4713.       Le code C définit "DOSBase" comme un XREF, alors que le code startup
  4714.       du E ;
  4715.       met à disposition cette valeur quelque part dans la pile,
  4716.     - les conventions d'appel/registre.
  4717.  
  4718. Je me suis débrouillé pour linker un petite fonction C en E qui fait peu de
  4719. chose, et l'appelle avec succès (ça a était fait avec MxonC++, dont le linker
  4720. utilise aussi la convention __ii des paramêtres).
  4721.  
  4722.  
  4723. 17G. bin/EYacc
  4724. --------------
  4725.  
  4726. C'est un portage du fameux Yacc d'unix, qui produit maintenant du code E au
  4727. lieu du code C. C'est seulement une première version, n'en attendez pas trop
  4728. de lui. Si vous n'avez aucune idée de ce que Yacc fait, lisez le texte à son
  4729. propos, car je ne le ferait pas ici entièrement.
  4730.  
  4731. Vous pouvez tout simplement écrire des sources .y comme d'habitude, seulement
  4732. où des actions doivent écrite en C, vous l'écrivez maintenant en E.
  4733. Reportez-vous à Src/Yacc/bcalc.y
  4734.  
  4735. Exemple :
  4736.  
  4737.     1> eyacc bcalc.y
  4738.  
  4739.     produit un fichier 'yyparse.e'
  4740.  
  4741.     1> ec yyparse
  4742.  
  4743.     vous donnera un module qui ne contient que la fonction yyparse(). Le reste
  4744.     de 'comment interfacer avec Yacc' doit être analogue au C.
  4745.  
  4746. [note: Je suis à la moitié de la traduction de Lex en E-Lex, mais pas encore
  4747. fini.]
  4748.  
  4749. Informations supplémentaires.
  4750.     E-Yacc est une modification du Yacc 1.8 de Berkeley, à l'origine par
  4751.     corbett@berkeley.edu. L'inclusion de cette version modifiée dans la
  4752.     distribution du E est tout à fait légale, comme l'auteur le certifie dans
  4753.     le README du BYacc1.8 original:
  4754.  
  4755. "   Berkeley Yacc is in the public domain.  The data structures and algorithms
  4756. used in Berkeley Yacc are all either taken from documents available to the
  4757. general public or are inventions of the author.  Anyone may freely distribute
  4758. source or binary forms of Berkeley Yacc whether unchanged or modified.
  4759. Distributers may charge whatever fees they can obtain for Berkeley Yacc.
  4760. Programs generated by Berkeley Yacc may be distributed freely. "
  4761.  
  4762. Traduction :
  4763.   Yacc de Berkeley est domaine public. Les structures de données et algorythmes
  4764. utilisé dans Yacc de Berkeley sont tous tirés de documents disponibles au grand
  4765. public ou sont l'invention de l'auteur. Chacun peut distribuer librement le
  4766. source ou des formes binaires du Yacc de Berkeley qu'il soit inchangé ou
  4767. modifié. Les distributeurs peuvent demander des droits qu'ils peuvent avoir
  4768. sur Yacc de Berkeley. Les programmes générés par Yacc de Berkeley sont
  4769. distribués gratuitement.
  4770.  
  4771.  
  4772. 17H. bin/SrcGen
  4773. ---------------
  4774.  
  4775. [note: cet utilitaire n'a pas été mis à jour pour mieux travailler avec le
  4776.  système de module du E, il sortira toujours un source 'raw' (qui peut être
  4777.  facilement incorporé dans n'importe quel module). Si il y a assez de demande
  4778.  je ferai une mise à jour. Si vous voulez ajouter une chouette interface
  4779.  graphique à votre programme, jetez un coup d'oeil à modules/tools/EasyGUI.m,
  4780.  ou à de nouveau outils comme le prochain BGUI de Jan van den Baard, l'auteur
  4781.  de GadToolsBox.]
  4782.  
  4783. ScrGen Générateur de source GadToolBox pour le E: version béta
  4784.  
  4785. Vous aurez besoin de GadToolBox v2.0 ou plus, et avoir la gadtoolsbox.library
  4786. qui vient avec, dans LIBS:. Maintenant, avec GTB, faites quelques exemples
  4787. simples (juste une fenêtre avec quelques gadgets et menus etc.), sauvez le sous
  4788. le nom "bla" (le nom de fichier sera "bla.gui"), et tapez:
  4789.  
  4790.     1> SrcGen bla
  4791.     1> EC bla
  4792.     1> bla
  4793.  
  4794. "bla.e" contient les routines pour ouvrir votre interface, tout comme les
  4795. routines qui prennent les messages idcmp, erreurs etc., et un "main" vide
  4796. qui attend juste une selection. Là vous pouvez mettre votre code.  Voyez la
  4797. ligne de commande de ScrGen pour savoir comment arrèter le génération de ces
  4798. routines.
  4799.  
  4800. C'est tout pour maintenant. Si vous avez des problêmes, vérifiez le source qui
  4801. a été généré.
  4802.  
  4803.  
  4804. 17I. bin/EBuild
  4805. ---------------
  4806.  
  4807. EBuild est un clone de "Make", et fonctionne tout comme lui. Build est un
  4808. outils qui vous aide à recompiler des parties importantes d'une grande
  4809. application après modification. Vous écrivez un fichier ".build" dans le
  4810. répertoire qui contient les sources de votre projet. Le fichier contient les
  4811. informations concernant les sources dépendant de quels autres, et quels
  4812. actions doivent être faites si un module ou un éxécutable à besoin d'être
  4813. recompilé. Build vérifie les dates des fichiers pour voir si le fichier a été
  4814. modifié depuis la dernière compilation, et si le source utilise des modules
  4815. qui ont été modifié, il les compilera en premier.
  4816.  
  4817. La syntaxe est celle de la version unix. En général, "#" précède les lignes
  4818. de commentaires, et:
  4819.  
  4820.     destination: dep1 dep2 ...
  4821.       action1
  4822.       action2
  4823.       ...
  4824.  
  4825. Destination est le fichier qui en résulte, dans la plupart des cas, un
  4826. éxéutable ou ou un module, mais peut^être autre chose aussi. Suivant les ":"
  4827. vous écrivez tout les fichiers s'y rapportant, etr principalement son source,
  4828. et d'autres modules. Les actions sur les lignes suivantes sont des commandes
  4829. AmigaDOS normales, et ont besoin d'être précédées par au moins un espace ou
  4830. une tabulation pour les différencier du fichiers destinations.
  4831.  
  4832.     bla: bla.e defs.m
  4833.          ec bla quiet
  4834.  
  4835. Ce simple exemple reompilera simplement 'bla.e' si il était modifié ou si
  4836. defs.m qu'il utilise l'a été.
  4837.  
  4838. Si vous tapez 'build' sans argument, Build s'assurera que le premier fichier
  4839. destination est mis à jour.
  4840.  
  4841.     TARGET,FROM/K,FORCE/S:
  4842.  
  4843. Si vous mettez une destination ('TARGET'), de cette façon Build commencera
  4844. avec une autre destination. FROM (de) vous permet de choisir un autre fichier
  4845. autre que ".build", et FORCE refera tout ce qui est dans le fichier sans se
  4846. soucier si c'était vraiment nécessaire.
  4847.  
  4848. Exemple:
  4849.  
  4850.  
  4851.     # fichier Build test
  4852.  
  4853.     tout:    bla burp
  4854.  
  4855.     defs.m: defs.e
  4856.             ec defs quiet
  4857.  
  4858.     truc:    truc.e defs.m
  4859.              ec truc quiet
  4860.  
  4861.     machin:   machin.e
  4862.               ec machin quiet
  4863.  
  4864.     nettoyer:
  4865.             delete  defs.m truc machin
  4866.  
  4867.  
  4868. Ce fichier Build concerne 2 programmes, 'truc' et 'machin'. Bla dépend du
  4869. module defs.m. Une destination supplémentaire 'nettoyer' a été ajouté comme
  4870. ça vous pouvez taper 'build nettoyer' pour effacer les fichiers créés.
  4871.  
  4872. D'autres dépendance et actions peuvenet être facilement ajouté. Par exemple,
  4873. si votre projet utilise un analyseur ('parser') généré par E-Yacc:
  4874.  
  4875.     yyparse.m: parser.y
  4876.                eyacc parser.y
  4877.                ec yyparse quiet
  4878.  
  4879. Ou mettez-y du code macro-assembleur comme module:
  4880.  
  4881.     blerk.m: blerk.s
  4882.              a68k blerk.s
  4883.              o2m blerk
  4884.              copy blerk.m emodules:tools
  4885.              flushcache tools/blerk
  4886.  
  4887. Une fois que vous connaitrez mieux Build, vous décrouvirez que vous pouvez
  4888. aussi l'utiliser pour d'autre utilisation quel celle-là. Voyez le comme un
  4889. outil de script intelligent.
  4890.  
  4891. Si vous voulez trouver les détails de ce que peut faire Build, lisez la
  4892. documentation de quelques 'make' d'unix, car Build devrait être compatible
  4893. avec eux. Ce qu'il ne fait pas pour le moment, est:
  4894.  
  4895. - régfir les dépendances de façon cyclique,
  4896. - permettre le "\" à la fin de longue ligne,
  4897. - les définitions de contantes.
  4898.  
  4899.  
  4900.  
  4901. +---------------------------------------------------------------+
  4902. |                 18. Appendices                                |
  4903. +---------------------------------------------------------------+
  4904.  
  4905.  
  4906. 18A. La grammaire E
  4907. -------------------
  4908.  
  4909. syntaxe lex   : expressions régulière
  4910. syntaxe parse : propre adaptation ASF/SDF
  4911.  
  4912.         name    = identificateur grammatical
  4913.         "name"  = constante
  4914.         ()      = groupe
  4915.         |       = ou
  4916.         e*      = 0 ou plus que e
  4917.         e+      = 1 ou plus que e
  4918.         {e s}*  = 0 ou plus que e séparaté par s
  4919.         {e s}+  = 1 ou plus que e séparaté par s
  4920.         [e]     = e est optionel
  4921.         ; e     = e est un commentaire :-)
  4922.  
  4923.  
  4924. LEX
  4925. ---
  4926.  
  4927. whitespace      = [ \t]         ; et \n si le dernier token est [,+-*/]
  4928.                                 ; ou similaire
  4929.                   n'importe quoi entre "/*" et "*/"
  4930.                   de "->" à \n
  4931. eol             = [;\n]
  4932.  
  4933. constant        = [A-Z] ( [A-Z] [A-Za-z0-9_]* )?
  4934. builtin         = [A-Z] [a-z] [A-Za-z0-9_]*
  4935. ident,objident  = [a-z] [a-zA-Z0-9_]*
  4936.  
  4937. num             = [0-9]+        ; "-" est un token séparé
  4938.                   $[0-9A-Fa-f]+
  4939.                   %[01]+
  4940. fnum            = [0-9]*.[0-9]*
  4941.  
  4942. stringconst     = n'importe quoi entre ''
  4943. charconst       = n'importe quoi entre ""
  4944.  
  4945.  
  4946. PARSE
  4947. -----
  4948.  
  4949. program         = opts globalpart localpart
  4950.  
  4951. globalpart      = ( modulestat | defstat | objdecl | constdecl | raisedecl )*
  4952. localpart       = ( procdecl | constdecl )+
  4953.  
  4954. modulestat      = "MODULE" { conststring "," }+ eol
  4955. defstat         = "DEF" vardecllist eol
  4956. objdecl         = "OBJECT" ident [ "OF" ident ] eol
  4957.                      ( vardecllist eol )+
  4958.                   "ENDOBJECT" eol
  4959. constdecl       = "CONST" { ( constant "=" constexp ) "," }+ |
  4960.                   "ENUM" { ( constant | constant "=" constexp ) "," }+ |
  4961.                   "SET" { constant "," }+
  4962. procdecl        = [ "EXPORT" ] "PROC" ident "(" argdecllist ")" [ "HANDLE" ]
  4963.                   ( "RETURN" { exp "," }* |
  4964.                      eol defstat* stats
  4965.                      [ "EXCEPT" eol stats ]
  4966.                      "ENDPROC" { exp "," }* eol )
  4967. raisedecl       = "RAISE" { ( constant "IF" builtin "()" compop num ) "," }+
  4968. opts            = ( "OPT" { setting "," }+ )*       ; dépendant de la machine
  4969.  
  4970. vardecllist     = { vardecl "," }+
  4971. vardecl         = ident [ "=" num ]
  4972.                     [ ":" ( "LONG" | "REAL" | "PTR" "TO" ptrtype ) ] |
  4973.                   ident ":" objtype |
  4974.                   ident "[" num "]" ":"
  4975.                     ( "ARRAY" |
  4976.                       "ARRAY" "OF" ptrtype |
  4977.                       "STRING" |
  4978.                       "LIST" )
  4979. argdecllist     = { argdecl "," }+
  4980. argdecl         = ident [ "=" defaultarg ]
  4981.                     [ ":" ( "LONG" | "REAL" | "PTR" "TO" ptrtype ) ]
  4982. ptrtype         = objtype | simpletype
  4983. simpletype      = CHAR | INT | LONG
  4984. objtype         = ident
  4985.  
  4986. stats           = ( ( onelinestat | multlinestat ) eol )*
  4987. onelinestat     = exp |
  4988.                   lval ":=" exp |
  4989.                   { var "," }+ ":=" exp |
  4990.                   "IF" exp "THEN" onelinestat "ELSE" onelinestat |
  4991.                   "FOR" var ":=" exp "TO" exp [ "STEP" num ]
  4992.                      "DO" onelinestat |
  4993.                   "WHILE" exp "DO" onelinestat |
  4994.                   "RETURN" { exp "," }* |
  4995.                   "JUMP" ident |
  4996.                   ( "INC" | "DEC" ) var |             ; presque obsolète
  4997.                   asm_mnemonic { operand "," }* |     ; dépendant de la machine
  4998.                   "INCBIN" stringconst |              ; support asm
  4999.                   simpletype { num "," }+ |
  5000.                   "VOID" exp                          ; obsolète
  5001. multlinestat    = "IF" exp eol stats
  5002.                      [ ( "ELSEIF" exp eol stats )* ]
  5003.                      [ "ELSE" eol stats ]
  5004.                      "ENDIF" |
  5005.                   "FOR" var ":=" exp "TO" exp [ "STEP" num ] eol
  5006.                      stats "ENDPROC" |
  5007.                   "WHILE" exp eol stats "ENDWHILE" |
  5008.                   "REPEAT" eol stats "UNTIL" exp |
  5009.                   "SELECT" var eol
  5010.                      ( "CASE" exp eol stats )+
  5011.                      [ "DEFAULT" eol stats ]
  5012.                      "ENDSELECT" |
  5013.                   "LOOP" eol stats "ENDLOOP"
  5014.  
  5015. explist         = { exp "," }+
  5016. exp             = [ "-" ] { item binop }+ |
  5017.                   exp "BUT" exp
  5018. item            = num | fnum | lval | stringconst | charconst |
  5019.                   "SIZEOF" objident |
  5020.                   "IF" exp "THEN" exp "ELSE" exp |
  5021.                   "[" explist "]" [ ":" ptrtype ] |
  5022.                   ( builtin | ident ) "(" explist ")" |
  5023.                   var ":=" exp |
  5024.                   "{" ident "}" |
  5025.                   "`" exp |
  5026. binop           = mathop | compop | logop
  5027. mathop          = "+" | "-" | "*" | "/"
  5028. compop          = "=" | "<>" | ">" | "<" | ">=" | "<="
  5029. logop           = "AND" | "OR"
  5030. constexp        = [ "-" ] { num ( "+" | "-" | "*" | "/" ) }+
  5031. lval            = var [ "[" [ exp ] "]" ] [ "." ident ] [ "++" | "--" ] |
  5032.                   "^" var [ "++" | "--" ] |
  5033. var             = ident
  5034. defaultarg      = num
  5035.  
  5036.  
  5037. 18B. Tutorial
  5038. -------------
  5039.  
  5040. Note : le tutorial original de l'Amiga E v2.1b a été supprimé, car il n'était
  5041. pas très utile, à mon humble opinion. A la place, Jason Hulance a écrit un
  5042. tutorial extensif sur le E dans lequel vous devrez absolument jeter un coup
  5043. d'oeil.
  5044.  
  5045.  
  5046. 18C. Comparaison du E avec C/C++/Pascal/Ada/Lisp etc.
  5047. -----------------------------------------------------
  5048.  
  5049. [des petits plus ont été aoujoté ici]
  5050.  
  5051. Dans les 2 premières colonnes, je compare le E avec le C/C++ ANSI. La
  5052. troisième colonne est réservée à un autre langage. J'y mettrais souvent le
  5053. Pascal, mais quand une des caractèristiques y apparait, j'en mettais un
  5054. autre (par exemple, le LISP et les expressions cotées, ADA et les exceptions).
  5055.  
  5056. Note : ne prenez pas ces tables à la lettre. J'ai essayé de marquer les
  5057. équivalences syntaxiques, et les propriétés sémantiques du mieux possible,
  5058. mais les différents langages possèdent leurs propre évaluation.
  5059.  
  5060. Si vous trouvez des erreurs dans la translation, faites le moi savoir, s'il
  5061. vous plait (en particulier pour le Pascal, les connaisances sont un peu
  5062. 'vieille')
  5063.  
  5064. signification des signes :
  5065.  
  5066. -       = cette caractèristique n'éxiste pas dans ce langage.
  5067. ?       = l'auteur n'est pas sur de la translation.
  5068. ...     = la caractèristique doit être possible, mais la translation n'est pas
  5069.           directe pour être intéressante.
  5070. x,y,z   = identificateurs arbitraires
  5071. e,f,g   = expressions arbitraires
  5072. s,t,u   = déclarations arbitraires
  5073. i,j,k   = entiers arbitraires
  5074. etc.
  5075.  
  5076.  
  5077. -----------------------------------------------------------------------
  5078. STRUCTURE/DÉCLARARTION
  5079.  
  5080. E                       C/C++                   Pascal
  5081. ----------------------- ----------------------- -----------------------
  5082. PROC x()                int x() {               FUNCTION x:INTEGER;
  5083. PROC x(y,z)             int x(y,z) {            FUNCTION x(y,z:INTEGER):INTEGER;
  5084. PROC x(y=1)             int x(y=1) {            -
  5085. ENDPROC                 return 0; };            x:=0; END;
  5086. ENDPROC e               return e; };            x:=e; END;
  5087. RETURN e                return e;               ?
  5088.  
  5089. IF e                    if(e) {                 IF e THEN BEGIN
  5090. ELSEIF e                } else if(e) {          END ELSE IF e THEN BEGIN
  5091. ELSE                    } else {                END ELSE BEGIN
  5092. ENDIF                   };                      END;
  5093. IF e THEN s             if(e) s;                IF e THEN s;
  5094. IF e THEN s ELSE t      if(e) s else t;         IF e THEN s ELSE t;
  5095.  
  5096. FOR x:=e TO f           - (1)                   FOR x:=e TO f DO BEGIN
  5097. FOR x:=e TO f STEP i    -                       - (2)
  5098. EXIT e                  if(e) break;            -
  5099. ENDFOR                  -                       END;
  5100. FOR x:=e TO f DO s      -                       FOR x:=e TO f DO s;
  5101.  
  5102. WHILE e                 while(e) {              WHILE e DO BEGIN
  5103. EXIT e                  if(e) break;            -
  5104. ENDWHILE                };                      END;
  5105. WHILE e DO s            while(e) s;             WHILE e DO s;
  5106.  
  5107. s; WHILE e              for(s;e;u) {            s; WHILE e DO BEGIN
  5108.   t; u                    t;                      t; u
  5109. ENDWHILE                };                      END;
  5110.  
  5111. REPEAT                  do {                    REPEAT
  5112. UNTIL e                 } while(!e);            UNTIL e;
  5113.  
  5114. LOOP                    for(;;) {               WHILE TRUE DO BEGIN (?)
  5115. ENDLOOP                 };                      END;
  5116.  
  5117. SELECT x                switch(x) {             CASE x OF
  5118. SELECT x OF y           switch(x) {             CASE x OF
  5119. CASE 1; s...            case 1: s...; break     1: BEGIN s... END
  5120. CASE a+1                -                       -
  5121. CASE 1,2,3              case 1: case 2: case3:  1,2,3:
  5122. CASE "a".."z"           -                       -
  5123. ENDSELECT               };                      END
  5124.  
  5125. INC x                   x++;                    x:=x+1; (INC())
  5126. DEC x                   x--;                    x:=x-1; (DEC())
  5127. JUMP lab                goto lab;               GOTO lab;
  5128. x:=e                    x=e;                    x:=e;
  5129.  
  5130. /* */                   /* */                   { }
  5131. ->                      //                      -
  5132.  
  5133. (1) voir WHILE; C n'a pas de FOR, "for" en C est une autre façon d'utiliser
  5134.     "while"
  5135. (2) uniquement STEP -1 pour DOWNTO
  5136.  
  5137.  
  5138. -----------------------------------------------------------------------
  5139. VALEURS
  5140.  
  5141. E                       C/C++                   Pascal
  5142. ----------------------- ----------------------- -----------------------
  5143. 1                       1                       1
  5144. 1.0                     1.0                     1.0
  5145. $1                      0x1                     ?
  5146. %1                      ?                       ?
  5147. "a"                     'a'                     chr(97) (?)
  5148. 'blabla'                "blabla"                'blabla'
  5149. [1,2,3]                 - (1)                   -
  5150. [1,2,3]:INT             -                       -
  5151.  
  5152. (1) dans la traduction de E en C, vous pouvez les simuler par :
  5153.  
  5154.     myfunc([1,2,3])
  5155.  
  5156. devient
  5157.  
  5158.     int dummy [] = {1,2,3};
  5159.     myfunc(dummy);
  5160.  
  5161.  
  5162. -----------------------------------------------------------------------
  5163. OPERATEURS
  5164.  
  5165. E                       C/C++                   Pascal
  5166. ----------------------- ----------------------- -----------------------
  5167. + - * /                 + - * /                 + - * DIV
  5168. = <> > < >= <=          == != > < >= <=         = <> > < >= <=
  5169. AND OR  (log)           && ||                   and or
  5170. AND OR  (bit)           & |                     ?
  5171. SIZEOF x                sizeof(x)               -
  5172. `e                      -                       - (1)
  5173. ^x      (4)             *x                      ...
  5174. {x}                     &x                      ...
  5175. x++                     x++                     -
  5176. x--                     --x                     -
  5177. -x                      -x                      -x
  5178. IF e THEN f ELSE g      e ? f : g               -
  5179. x.y                     x->y    x.y             x^.y    x.y
  5180. a:=x.y; a.z             x->y->z x.y.z           x^.y^.z x.y.z
  5181. x:=e                    x=e                     -
  5182. e BUT f                 (e,f)                   -
  5183. x[]                     x[0] *x (2)             x[0]
  5184. x[1]                    x[1]                    x[1]
  5185. x[1]    (3)             &x[1]                   ?
  5186. x[1].y                  x[1]->y                 x[1]^.y
  5187. x[]++                   *x++                    -
  5188. x[1].y++                *(x+1)++                -
  5189. x::y.a                  ((y *)x)->a             -
  5190. x.y::z.a                ((z *)x->y)->a          -
  5191.  
  5192. (1) voir EXPRESSIONS COTÉES
  5193. (2) de même pour d'autres, les équivalences entre *(x+e) et x[e] sont faites.
  5194. (3) si ARRAY OF <objet>
  5195. (4) SEULEMENT pour donner en référence. sinon: "[]"
  5196.  
  5197.  
  5198. -----------------------------------------------------------------------
  5199. CONSTANTES/TYPES
  5200.  
  5201. E                       C/C++                   Pascal
  5202. ----------------------- ----------------------- -----------------------
  5203. CONST X=1               #define X 1             CONST X=1;
  5204.                         const int X=1;
  5205. ENUM X,Y,Z              #define X 0 (etc.)      TYPE x=(X,Y,Z);
  5206.                         enum x{X,Y,Z};
  5207. SET X,Y,Z               -                       TYPE x=SET OF (X,Y,Z);
  5208.  
  5209. DEF                                             VAR
  5210. x                       int x; (or: long x;)    x:INTEGER;
  5211. x:LONG                  int x;                  x:INTEGER;
  5212. x:PTR TO y              struct y* x;            x:^y;
  5213. x:y                     struct y x;             x:y;
  5214. x[10]:ARRAY OF y        struct y x[10];         x:ARRAY [0..9] OF y;
  5215. x[10]:STRING            - (1)                   x:STRING[10]; (2)
  5216. x[10]:LIST              - (1)                   - (1)
  5217.  
  5218. x:REG                   register int x;
  5219.  
  5220. OBJECT x                struct x {      (3)     TYPE x = RECORD
  5221.   y:CHAR,z:INT            char y; short z;        y:CHAR; z:INTEGER;
  5222. ENDOBJECT               };                      END;
  5223.  
  5224. (1) dans la traduction de E en C, simulez avec un tableau de char/int
  5225.     respectivement, et faites votre propre vérification, etc.
  5226. (2) n'est pas dans le Pascal standard, mais possible dans tous les dialectes.
  5227. (3) ou de classe publique (public class) bien sûr...
  5228.  
  5229.  
  5230. -----------------------------------------------------------------------
  5231. EXPRESSIONS COTÉES
  5232.  
  5233. E                       LISP                        MIRANDA
  5234. ----------------------- --------------------------- -------------------
  5235. `e                      (QUOTE e)  'e               (3)
  5236.                         (LAMBDA () e)     (1)
  5237. `x+y                    '(+ x y)
  5238. Eval(`e)                (EVAL `e)
  5239. ForAll(v,l,`e)          - (2)
  5240. MapList(v,l,l,`e)       (MAPCAR (LAMBDA (V) E) L)   map (\v->e) l
  5241.  
  5242. exemple:
  5243.  
  5244. E:              MapList({x},[1,2,3,4],a,`x*x)
  5245. MIRANDA:        map (\x->x*x) [1,2,3,4]
  5246. LISP:           (MAPCAR (LAMBDA (X) (* X X) `(1 2 3 4))
  5247.  
  5248. (1) de vraies cotes `, mais des fois utilisés, où en LIST, la fonction LAMBDA
  5249.     aurait été utilisé, comme MapList().
  5250. (2) même pas en Prolog, voir d'autres langages logiques.
  5251. (3) on sera plutôt flemmard ici
  5252.  
  5253.  
  5254. -----------------------------------------------------------------------
  5255. UNIFICATION AND CELLULES LISP
  5256.  
  5257. E                       LISP                    PROLOG
  5258. ----------------------- ----------------------- -----------------------
  5259. <1|2>                   (1 . 2)                 [1|2]
  5260. <1,2,3>                 (1 2 3)                 [1,2,3]
  5261. <1,2|3>                 (1 2 . 3)               [1,2|3]
  5262.  
  5263. E                       HASKELL                 PROLOG
  5264. ----------------------- ----------------------- -----------------------
  5265. e <=> <x|y>             (x:y) = e               e = [X|Y]
  5266. e <=> <1,2,x>           [1,2,x] = e             e = [1,2,X]
  5267. e <=> [1,x]             -                       -
  5268.  
  5269.  
  5270. -----------------------------------------------------------------------
  5271. EXCEPTIONS
  5272.  
  5273. E                       C++                     ADA
  5274. ----------------------- ----------------------- -----------------------
  5275. PROC x() HANDLE         int x() { try {         function x is begin
  5276. EXCEPT                  } catch (exc) {   (1)   exception
  5277. EXCEPT DO               -                       -
  5278. ENDPROC                 }};                     end x;
  5279.  
  5280. Raise(e)                throw e;                raise e;
  5281. Throw(e,f)              ?                       -
  5282. ReThrow()               throw e;                raise e;
  5283. RAISE "MEM" IF New()=0  -                       - (2)
  5284.  
  5285.  
  5286. (1) catch gère un seule exception, c'est différent des gestionnaires
  5287.     d'exception généraux comme utilisé en E.
  5288. (2) le système ne lève que uelques exceptions, mais je ne suis pas sûr si
  5289.     des levées d'exceptions automatiques peuvent être définies en Ada.
  5290.  
  5291.  
  5292. -----------------------------------------------------------------------
  5293. PROGRAMMATION ORIENTÉ OBJET
  5294.  
  5295. E                               C++
  5296. ------------------------------- -----------------------
  5297. OBJECT x                        class x {
  5298. OBJECT x OF y                   class x : y {
  5299. self.i                          this->i
  5300. PROC a OF x IS self.i           virtual int x::a() { return i; }
  5301. -                               int x::a() { return i; }
  5302. PROC a OF x IS EMPTY            virtual int x::a() =0
  5303. PUBLIC                          public:
  5304. a.method(1)                     a->method(1)
  5305.  
  5306. [voir aussi la prochaine partie sous NEW]
  5307.  
  5308. -----------------------------------------------------------------------
  5309. FONCTIONS PRÉDÉFINIES (BUILT-IN)
  5310. (seulement quelques uns sont là, comme exemple)
  5311.  
  5312. E                       C/C++                   Pascal
  5313. ----------------------- ----------------------- -----------------------
  5314. WriteF(fs,...)          printf(fs,...);         WriteLn(a,b,...);
  5315.                         cout << a << b ... ;
  5316.  
  5317. ReadStr(f,s)            scanf(fs,...)           ReadLn(s)
  5318. Val(s,n)                                        Val()
  5319.                         cin >> s;
  5320.  
  5321. StrCopy(s,s,n)  (1)     strcpy(s,s)             s:=s; (2)
  5322.  
  5323. Mod(e,e)                e%e                     e MOD e
  5324. Shl(e,n)                e<<n                    Shl()
  5325. Long(e)                 -                       -
  5326.  
  5327. p:=New(e)               p=malloc(e);            New(p);
  5328. NEW p                   p=new type;
  5329. NEW p.constr()          p=new constr()          -
  5330. NEW [e,f,g]             -                       -
  5331. Dispose(p)              free(p);                Dispose(p);
  5332.                         delete p;
  5333.  
  5334. (1) en traduisant du C, fait attention à transformer les tableaux de char en
  5335.     chaines (string).
  5336. (2) ch'sait pas quelle fonction est nécessaire dans le cas d'un pointeur.
  5337.